From d9f78fdffea95b54b96c2fe1f06ee565c7312375 Mon Sep 17 00:00:00 2001 From: stranger Date: Thu, 9 Aug 2007 13:07:21 +0000 Subject: [PATCH 1/1] * creating branch with HISA plug-in - due tu critical bug we need to remove for this moment this from standard package git-svn-id: file:///svnroot/mdictionary/branches/home_applet_plugin@164 5bde0345-f819-0410-ac75-e5045f9217cc --- Makefile | 335 +++ README | 48 + add_dict | 23 + data/bookmarks/bdb/bm_trans.db | Bin 0 -> 8192 bytes data/bookmarks/bdb/bm_words.db | Bin 0 -> 8192 bytes data/bookmarks/sql/ws_bookmarks | Bin 0 -> 3072 bytes data/bookmarks/sql3/ws_bookmarks3 | Bin 0 -> 2048 bytes data/bookmarks/xdxf/ws_bookmarks.xdxf | 7 + .../dictionaries/StarDictSampleDict/sample.dict.dz | 1 + data/dictionaries/StarDictSampleDict/sample.idx | Bin 0 -> 4539 bytes data/dictionaries/StarDictSampleDict/sample.ifo | 6 + data/dictionaries/XDXFSampleDict/dict.xdxf | 214 ++ data/docs/whitestork/changelog | 5 + data/docs/whitestork/changelog.Debian | 2 + data/docs/whitestork/copyright | 3 + data/docs/whitestorkdictionary/changelog | 5 + data/docs/whitestorkdictionary/changelog.Debian | 1 + data/docs/whitestorkdictionary/copyright | 3 + data/docs/whitestorkgui/changelog | 5 + data/docs/whitestorkgui/changelog.Debian | 2 + data/docs/whitestorkgui/copyright | 3 + data/docs/whitestorkplugins/changelog | 5 + data/docs/whitestorkplugins/changelog.Debian | 3 + data/docs/whitestorkplugins/copyright | 3 + data/icons/engine_xdxf_icon.png | Bin 0 -> 944 bytes data/icons/engine_xdxf_icon_2.png | Bin 0 -> 210 bytes data/icons/qgn_indi_search_whitestork.png | Bin 0 -> 1563 bytes data/icons/whitestork.png | Bin 0 -> 749 bytes data/icons/whitestork_icon.png | Bin 0 -> 277 bytes data/icons/ws_top.png | Bin 0 -> 280 bytes data/icons/ws_tra.png | Bin 0 -> 507 bytes data/icons/ws_warning_icon.png | Bin 0 -> 781 bytes data/locale/POTFILES.in | 5 + data/locale/en_GB.po | 353 +++ data/locale/es.po | 354 +++ data/locale/pl_PL.po | 348 +++ data/mis/whitestork-search.xml | 5 + data/other/org.maemo.WhiteStorkGui.service | 4 + data/other/org.maemo.WhiteStorkManager.service | 4 + data/other/whitestork.desktop | 20 + data/package_contents/whitestork/DEBIAN/control | 31 + data/package_contents/whitestork/DEBIAN/postinst | 23 + data/package_contents/whitestork/DEBIAN/postrm | 3 + data/package_contents/whitestork/DEBIAN/preinst | 3 + data/package_contents/whitestork/DEBIAN/prerm | 14 + .../whitestorkdictionary/DEBIAN/control | 12 + .../whitestorkdictionary/DEBIAN/postinst | 3 + .../whitestorkdictionary/DEBIAN/postrm | 3 + .../whitestorkdictionary/DEBIAN/preinst | 3 + .../whitestorkdictionary/DEBIAN/prerm | 3 + data/package_contents/whitestorkgui/DEBIAN/control | 27 + .../package_contents/whitestorkgui/DEBIAN/postinst | 17 + data/package_contents/whitestorkgui/DEBIAN/postrm | 4 + data/package_contents/whitestorkgui/DEBIAN/preinst | 3 + data/package_contents/whitestorkgui/DEBIAN/prerm | 7 + .../whitestorkplugins/DEBIAN/control | 25 + .../whitestorkplugins/DEBIAN/postinst | 13 + .../whitestorkplugins/DEBIAN/postrm | 3 + .../whitestorkplugins/DEBIAN/preinst | 3 + .../whitestorkplugins/DEBIAN/prerm | 12 + debian/changelog | 20 + debian/compat | 1 + debian/control | 89 + debian/copyright | 15 + debian/files | 3 + debian/rules | 100 + debian/whitestork.postinst | 18 + debian/whitestork.prerm | 14 + debian/whitestork.substvars | 1 + debian/whitestork/DEBIAN/control | 33 + debian/whitestork/DEBIAN/md5sums | 8 + debian/whitestork/DEBIAN/postinst | 18 + debian/whitestork/DEBIAN/prerm | 14 + debian/whitestork/usr/bin/WhiteStorkManager | Bin 0 -> 36804 bytes .../whitestork/usr/lib/WhiteStork/ws_bookmark.so | Bin 0 -> 30340 bytes .../WhiteStork/dictionaries/bookmarks/bm_trans.db | Bin 0 -> 8192 bytes .../WhiteStork/dictionaries/bookmarks/bm_words.db | Bin 0 -> 8192 bytes .../services/org.maemo.WhiteStorkManager.service | 4 + .../usr/share/doc/whitestork/changelog.Debian.gz | Bin 0 -> 406 bytes .../usr/share/doc/whitestork/changelog.gz | Bin 0 -> 107 bytes .../whitestork/usr/share/doc/whitestork/copyright | 15 + debian/whitestorkgui.postinst | 25 + debian/whitestorkgui.prerm | 32 + debian/whitestorkgui.substvars | 1 + debian/whitestorkgui/DEBIAN/control | 34 + debian/whitestorkgui/DEBIAN/md5sums | 15 + debian/whitestorkgui/DEBIAN/postinst | 25 + debian/whitestorkgui/DEBIAN/prerm | 32 + debian/whitestorkgui/usr/bin/WhiteStork | Bin 0 -> 73572 bytes .../share/applications/hildon/whitestork.desktop | 20 + .../services/org.maemo.WhiteStorkGui.service | 4 + .../share/doc/whitestorkgui/changelog.Debian.gz | Bin 0 -> 406 bytes .../usr/share/doc/whitestorkgui/copyright | 15 + .../share/locale/en_GB/LC_MESSAGES/whitestork.mo | Bin 0 -> 5367 bytes .../usr/share/locale/es/LC_MESSAGES/whitestork.mo | Bin 0 -> 5577 bytes .../share/locale/pl_PL/LC_MESSAGES/whitestork.mo | Bin 0 -> 5430 bytes .../usr/share/mis/whitestork-search.xml | 5 + .../share/pixmaps/qgn_indi_search_whitestork.png | Bin 0 -> 1563 bytes .../whitestorkgui/usr/share/pixmaps/whitestork.png | Bin 0 -> 749 bytes .../usr/share/pixmaps/whitestork_icon.png | Bin 0 -> 277 bytes debian/whitestorkgui/usr/share/pixmaps/ws_top.png | Bin 0 -> 280 bytes debian/whitestorkgui/usr/share/pixmaps/ws_tra.png | Bin 0 -> 507 bytes .../usr/share/pixmaps/ws_warning_icon.png | Bin 0 -> 781 bytes debian/whitestorkplugins.postinst | 23 + debian/whitestorkplugins.substvars | 1 + debian/whitestorkplugins/DEBIAN/control | 24 + debian/whitestorkplugins/DEBIAN/md5sums | 9 + debian/whitestorkplugins/DEBIAN/postinst | 23 + .../usr/lib/WhiteStork/engine_stardict.so | Bin 0 -> 65752 bytes .../usr/lib/WhiteStork/engine_xdxf.so | Bin 0 -> 34484 bytes .../dictionaries/StarDictSampleDict/sample.dict.dz | 1 + .../dictionaries/StarDictSampleDict/sample.idx | Bin 0 -> 4539 bytes .../dictionaries/StarDictSampleDict/sample.ifo | 6 + .../dictionaries/XDXFSampleDict/dict.xdxf | 214 ++ .../doc/whitestorkplugins/changelog.Debian.gz | Bin 0 -> 406 bytes .../usr/share/doc/whitestorkplugins/copyright | 15 + .../usr/share/pixmaps/engine_xdxf_icon.png | Bin 0 -> 944 bytes generate_locale | 9 + generate_repo | 12 + include/dictionary_engine.h | 296 +++ include/ws_dbus.h | 275 +++ logs/clean.log | 33 + po/POTFILES.in | 5 + po/domain.mo | Bin 0 -> 2141 bytes po/en_GB.po | 313 +++ po/pl_PL.po | 550 +++++ po/pl_Pl.po | 288 +++ po/template.po | 534 +++++ po/whitestork.mo | Bin 0 -> 2955 bytes src/bookmarks/bdb/COPYING | 339 +++ src/bookmarks/bdb/Makefile | 71 + src/bookmarks/bdb/data/bm_trans.db | Bin 0 -> 8192 bytes src/bookmarks/bdb/data/bm_words.db | Bin 0 -> 8192 bytes src/bookmarks/bdb/include/.kateconfig | 1 + src/bookmarks/bdb/include/engine_bookmark.h | 238 ++ src/bookmarks/bdb/src/.kateconfig | 1 + src/bookmarks/bdb/src/berkeleyRead.c | 504 +++++ src/bookmarks/bdb/src/engine_bookmark.c | 1368 ++++++++++++ src/bookmarks/bdb/src/test.c | 160 ++ src/bookmarks/bdb/src/testMakeDatabase.c | 135 ++ src/bookmarks/sql/COPYING | 339 +++ src/bookmarks/sql/Makefile | 48 + src/bookmarks/sql/include/engine_bookmark.h | 210 ++ src/bookmarks/sql/src/engine_bookmark.c | 1055 +++++++++ src/bookmarks/sql/src/test.c | 144 ++ src/bookmarks/sql/src/testMakeDatabase.c | 135 ++ src/bookmarks/sql3/COPYING | 339 +++ src/bookmarks/sql3/Makefile | 48 + src/bookmarks/sql3/include/engine_bookmark.h | 210 ++ src/bookmarks/sql3/src/engine_bookmark.c | 1020 +++++++++ src/bookmarks/sql3/src/test.c | 144 ++ src/bookmarks/sql3/src/testMakeDatabase.c | 135 ++ src/bookmarks/xdxf/COPYING | 339 +++ src/bookmarks/xdxf/Makefile | 44 + src/bookmarks/xdxf/include/engine_bookmark.h | 326 +++ src/bookmarks/xdxf/src/engine_bookmark.c | 1995 +++++++++++++++++ src/bookmarks/xdxf/src/engine_bookmark_old.c | 975 ++++++++ src/bookmarks/xdxf/src/test.c | 144 ++ src/bookmarks/xdxf/src/test1.c | 144 ++ src/bookmarks/xdxf/src/test2.c | 28 + src/bookmarks/xdxf/src/testMakeDatabase.c | 135 ++ src/dbus_wrapper/COPYING | 504 +++++ src/dbus_wrapper/Doxyfile | 1237 ++++++++++ src/dbus_wrapper/Makefile | 21 + src/dbus_wrapper/src/ws_dbus.c | 891 ++++++++ src/gui/include/pc-instances.h | 79 + src/gui/include/ws_gui.h | 277 +++ src/gui/include/ws_gui_callbacks.h | 264 +++ src/gui/include/ws_gui_layout.h | 134 ++ src/gui/makefile | 50 + src/gui/src/pc-instances.c | 169 ++ src/gui/src/ws_gui.c | 185 ++ src/gui/src/ws_gui_callbacks.c | 2354 ++++++++++++++++++++ src/gui/src/ws_gui_layout.c | 1789 +++++++++++++++ src/manager/COPYING | 339 +++ src/manager/Makefile | 36 + src/manager/commit | 2 + src/manager/include/pc-instances.h | 79 + src/manager/include/untar.h | 16 + src/manager/include/ws_manager.h | 117 + src/manager/include/ws_mng_bookmarks_utils.h | 59 + src/manager/include/ws_mng_callbacks.h | 52 + src/manager/include/ws_mng_dictionary_utils.h | 53 + src/manager/include/ws_mng_gconf_utils.h | 64 + src/manager/include/ws_mng_searching_threads.h | 88 + src/manager/include/ws_mng_threads_utils.h | 49 + src/manager/src/untar.c | 231 ++ src/manager/src/whitestork.c | 48 + src/manager/src/ws_manager.c | 335 +++ src/manager/src/ws_mng_bookmarks_utils.c | 167 ++ src/manager/src/ws_mng_callbacks.c | 249 +++ src/manager/src/ws_mng_dictionary_utils.c | 135 ++ src/manager/src/ws_mng_gconf_utils.c | 257 +++ src/manager/src/ws_mng_searching_threads.c | 335 +++ src/manager/src/ws_mng_threads_utils.c | 131 ++ src/manager_copy/COPYING | 339 +++ src/manager_copy/bin/WhiteStorkManager | Bin 0 -> 82553 bytes src/manager_copy/include/pc-instances.h | 79 + src/manager_copy/include/untar.h | 16 + src/manager_copy/include/ws_manager.h | 182 ++ src/manager_copy/makefile | 35 + src/manager_copy/src/pc-instances.c | 169 ++ src/manager_copy/src/untar.c | 229 ++ src/manager_copy/src/whitestork.c | 60 + src/manager_copy/src/ws_manager.c | 1376 ++++++++++++ src/plugins/stardict/COPYING | 339 +++ src/plugins/stardict/Makefile | 56 + src/plugins/stardict/doc/DICTFILE_FORMAT | 465 ++++ src/plugins/stardict/include/data.h | 57 + src/plugins/stardict/include/defs.h | 279 +++ src/plugins/stardict/include/dictP.h | 343 +++ src/plugins/stardict/include/dictd.h | 127 ++ src/plugins/stardict/include/dictzip.h | 120 + src/plugins/stardict/include/engine API.h | 898 ++++++++ src/plugins/stardict/include/engine_stardict.h | 324 +++ src/plugins/stardict/include/maa.h | 603 +++++ src/plugins/stardict/precompiled/arm/data.o | Bin 0 -> 22016 bytes src/plugins/stardict/precompiled/arm/debug.o | Bin 0 -> 11136 bytes src/plugins/stardict/precompiled/arm/error.o | Bin 0 -> 8352 bytes src/plugins/stardict/precompiled/arm/hash.o | Bin 0 -> 19680 bytes src/plugins/stardict/precompiled/arm/log.o | Bin 0 -> 15428 bytes src/plugins/stardict/precompiled/arm/memory.o | Bin 0 -> 16192 bytes src/plugins/stardict/precompiled/arm/prime.o | Bin 0 -> 4372 bytes src/plugins/stardict/precompiled/arm/stack.o | Bin 0 -> 6904 bytes src/plugins/stardict/precompiled/arm/string.o | Bin 0 -> 15076 bytes src/plugins/stardict/precompiled/arm/xmalloc.o | Bin 0 -> 6568 bytes src/plugins/stardict/precompiled/i686/data.o | Bin 0 -> 22876 bytes src/plugins/stardict/precompiled/i686/debug.o | Bin 0 -> 10284 bytes src/plugins/stardict/precompiled/i686/error.o | Bin 0 -> 7856 bytes src/plugins/stardict/precompiled/i686/hash.o | Bin 0 -> 17508 bytes src/plugins/stardict/precompiled/i686/log.o | Bin 0 -> 14540 bytes src/plugins/stardict/precompiled/i686/memory.o | Bin 0 -> 14860 bytes src/plugins/stardict/precompiled/i686/prime.o | Bin 0 -> 4268 bytes src/plugins/stardict/precompiled/i686/stack.o | Bin 0 -> 6720 bytes src/plugins/stardict/precompiled/i686/string.o | Bin 0 -> 14076 bytes src/plugins/stardict/precompiled/i686/xmalloc.o | Bin 0 -> 6200 bytes src/plugins/stardict/src/engine_stardict.c | 1730 ++++++++++++++ src/plugins/stardict/src/test.c | 133 ++ src/plugins/stardict/test_dictsip/data.c | 524 +++++ src/plugins/stardict/test_dictsip/data.h | 56 + src/plugins/stardict/test_dictsip/dictd.c | 1962 ++++++++++++++++ src/plugins/stardict/test_dictsip/dictd.h | 127 ++ src/plugins/stardict/test_dictsip/dictzip.c | 529 +++++ src/plugins/stardict/test_dictsip/dictzip.h | 120 + src/plugins/xdxf/COPYING | 339 +++ src/plugins/xdxf/Makefile | 43 + src/plugins/xdxf/include/engine_xdxf.h | 334 +++ src/plugins/xdxf/src/engine_xdxf.c | 1677 ++++++++++++++ src/plugins/xdxf/src/test.c | 114 + 249 files changed, 40525 insertions(+) create mode 100644 Makefile create mode 100644 README create mode 100755 add_dict create mode 100644 data/bookmarks/bdb/bm_trans.db create mode 100644 data/bookmarks/bdb/bm_words.db create mode 100644 data/bookmarks/sql/ws_bookmarks create mode 100644 data/bookmarks/sql3/ws_bookmarks3 create mode 100644 data/bookmarks/xdxf/ws_bookmarks.cache create mode 100644 data/bookmarks/xdxf/ws_bookmarks.xdxf create mode 100644 data/dictionaries/StarDictSampleDict/sample.dict.dz create mode 100644 data/dictionaries/StarDictSampleDict/sample.idx create mode 100644 data/dictionaries/StarDictSampleDict/sample.ifo create mode 100644 data/dictionaries/XDXFSampleDict/dict.xdxf create mode 100644 data/docs/whitestork/changelog create mode 100644 data/docs/whitestork/changelog.Debian create mode 100644 data/docs/whitestork/copyright create mode 100644 data/docs/whitestorkdictionary/changelog create mode 100644 data/docs/whitestorkdictionary/changelog.Debian create mode 100644 data/docs/whitestorkdictionary/copyright create mode 100644 data/docs/whitestorkgui/changelog create mode 100644 data/docs/whitestorkgui/changelog.Debian create mode 100644 data/docs/whitestorkgui/copyright create mode 100644 data/docs/whitestorkplugins/changelog create mode 100644 data/docs/whitestorkplugins/changelog.Debian create mode 100644 data/docs/whitestorkplugins/copyright create mode 100644 data/icons/engine_xdxf_icon.png create mode 100644 data/icons/engine_xdxf_icon_2.png create mode 100644 data/icons/qgn_indi_search_whitestork.png create mode 100644 data/icons/whitestork.png create mode 100644 data/icons/whitestork_icon.png create mode 100644 data/icons/ws_top.png create mode 100644 data/icons/ws_tra.png create mode 100644 data/icons/ws_warning_icon.png create mode 100644 data/locale/POTFILES.in create mode 100644 data/locale/en_GB.po create mode 100644 data/locale/es.po create mode 100644 data/locale/pl_PL.po create mode 100644 data/mis/whitestork-search.xml create mode 100644 data/other/org.maemo.WhiteStorkGui.service create mode 100644 data/other/org.maemo.WhiteStorkManager.service create mode 100644 data/other/whitestork.desktop create mode 100644 data/package_contents/whitestork/DEBIAN/control create mode 100755 data/package_contents/whitestork/DEBIAN/postinst create mode 100755 data/package_contents/whitestork/DEBIAN/postrm create mode 100755 data/package_contents/whitestork/DEBIAN/preinst create mode 100755 data/package_contents/whitestork/DEBIAN/prerm create mode 100644 data/package_contents/whitestorkdictionary/DEBIAN/control create mode 100755 data/package_contents/whitestorkdictionary/DEBIAN/postinst create mode 100755 data/package_contents/whitestorkdictionary/DEBIAN/postrm create mode 100755 data/package_contents/whitestorkdictionary/DEBIAN/preinst create mode 100755 data/package_contents/whitestorkdictionary/DEBIAN/prerm create mode 100644 data/package_contents/whitestorkgui/DEBIAN/control create mode 100755 data/package_contents/whitestorkgui/DEBIAN/postinst create mode 100755 data/package_contents/whitestorkgui/DEBIAN/postrm create mode 100755 data/package_contents/whitestorkgui/DEBIAN/preinst create mode 100755 data/package_contents/whitestorkgui/DEBIAN/prerm create mode 100644 data/package_contents/whitestorkplugins/DEBIAN/control create mode 100755 data/package_contents/whitestorkplugins/DEBIAN/postinst create mode 100755 data/package_contents/whitestorkplugins/DEBIAN/postrm create mode 100755 data/package_contents/whitestorkplugins/DEBIAN/preinst create mode 100755 data/package_contents/whitestorkplugins/DEBIAN/prerm create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/docs create mode 100644 debian/files create mode 100755 debian/rules create mode 100755 debian/whitestork.postinst create mode 100755 debian/whitestork.prerm create mode 100644 debian/whitestork.substvars create mode 100644 debian/whitestork/DEBIAN/control create mode 100644 debian/whitestork/DEBIAN/md5sums create mode 100755 debian/whitestork/DEBIAN/postinst create mode 100755 debian/whitestork/DEBIAN/prerm create mode 100755 debian/whitestork/usr/bin/WhiteStorkManager create mode 100644 debian/whitestork/usr/lib/WhiteStork/ws_bookmark.so create mode 100644 debian/whitestork/usr/share/WhiteStork/dictionaries/bookmarks/bm_trans.db create mode 100644 debian/whitestork/usr/share/WhiteStork/dictionaries/bookmarks/bm_words.db create mode 100644 debian/whitestork/usr/share/dbus-1/services/org.maemo.WhiteStorkManager.service create mode 100644 debian/whitestork/usr/share/doc/whitestork/changelog.Debian.gz create mode 100644 debian/whitestork/usr/share/doc/whitestork/changelog.gz create mode 100644 debian/whitestork/usr/share/doc/whitestork/copyright create mode 100755 debian/whitestorkgui.postinst create mode 100755 debian/whitestorkgui.prerm create mode 100644 debian/whitestorkgui.substvars create mode 100644 debian/whitestorkgui/DEBIAN/control create mode 100644 debian/whitestorkgui/DEBIAN/md5sums create mode 100755 debian/whitestorkgui/DEBIAN/postinst create mode 100755 debian/whitestorkgui/DEBIAN/prerm create mode 100755 debian/whitestorkgui/usr/bin/WhiteStork create mode 100644 debian/whitestorkgui/usr/share/applications/hildon/whitestork.desktop create mode 100644 debian/whitestorkgui/usr/share/dbus-1/services/org.maemo.WhiteStorkGui.service create mode 100644 debian/whitestorkgui/usr/share/doc/whitestorkgui/changelog.Debian.gz create mode 100644 debian/whitestorkgui/usr/share/doc/whitestorkgui/copyright create mode 100644 debian/whitestorkgui/usr/share/locale/en_GB/LC_MESSAGES/whitestork.mo create mode 100644 debian/whitestorkgui/usr/share/locale/es/LC_MESSAGES/whitestork.mo create mode 100644 debian/whitestorkgui/usr/share/locale/pl_PL/LC_MESSAGES/whitestork.mo create mode 100644 debian/whitestorkgui/usr/share/mis/whitestork-search.xml create mode 100644 debian/whitestorkgui/usr/share/pixmaps/qgn_indi_search_whitestork.png create mode 100644 debian/whitestorkgui/usr/share/pixmaps/whitestork.png create mode 100644 debian/whitestorkgui/usr/share/pixmaps/whitestork_icon.png create mode 100644 debian/whitestorkgui/usr/share/pixmaps/ws_top.png create mode 100644 debian/whitestorkgui/usr/share/pixmaps/ws_tra.png create mode 100644 debian/whitestorkgui/usr/share/pixmaps/ws_warning_icon.png create mode 100755 debian/whitestorkplugins.postinst create mode 100644 debian/whitestorkplugins.substvars create mode 100644 debian/whitestorkplugins/DEBIAN/control create mode 100644 debian/whitestorkplugins/DEBIAN/md5sums create mode 100755 debian/whitestorkplugins/DEBIAN/postinst create mode 100644 debian/whitestorkplugins/usr/lib/WhiteStork/engine_stardict.so create mode 100644 debian/whitestorkplugins/usr/lib/WhiteStork/engine_xdxf.so create mode 100644 debian/whitestorkplugins/usr/share/WhiteStork/dictionaries/StarDictSampleDict/sample.dict.dz create mode 100644 debian/whitestorkplugins/usr/share/WhiteStork/dictionaries/StarDictSampleDict/sample.idx create mode 100644 debian/whitestorkplugins/usr/share/WhiteStork/dictionaries/StarDictSampleDict/sample.ifo create mode 100644 debian/whitestorkplugins/usr/share/WhiteStork/dictionaries/XDXFSampleDict/dict.xdxf create mode 100644 debian/whitestorkplugins/usr/share/doc/whitestorkplugins/changelog.Debian.gz create mode 100644 debian/whitestorkplugins/usr/share/doc/whitestorkplugins/copyright create mode 100644 debian/whitestorkplugins/usr/share/pixmaps/engine_xdxf_icon.png create mode 100755 generate_locale create mode 100755 generate_repo create mode 100644 include/dictionary_engine.h create mode 100644 include/ws_dbus.h create mode 100644 logs/clean.log create mode 100644 po/POTFILES.in create mode 100644 po/domain.mo create mode 100644 po/en_GB.po create mode 100644 po/pl_PL.po create mode 100644 po/pl_Pl.po create mode 100644 po/template.po create mode 100644 po/whitestork.mo create mode 100755 src/bookmarks/bdb/COPYING create mode 100755 src/bookmarks/bdb/Makefile create mode 100755 src/bookmarks/bdb/data/bm_trans.db create mode 100755 src/bookmarks/bdb/data/bm_words.db create mode 100755 src/bookmarks/bdb/include/.kateconfig create mode 100755 src/bookmarks/bdb/include/engine_bookmark.h create mode 100755 src/bookmarks/bdb/src/.kateconfig create mode 100644 src/bookmarks/bdb/src/berkeleyRead.c create mode 100755 src/bookmarks/bdb/src/engine_bookmark.c create mode 100755 src/bookmarks/bdb/src/test.c create mode 100755 src/bookmarks/bdb/src/testMakeDatabase.c create mode 100644 src/bookmarks/sql/COPYING create mode 100644 src/bookmarks/sql/Makefile create mode 100644 src/bookmarks/sql/include/engine_bookmark.h create mode 100644 src/bookmarks/sql/src/engine_bookmark.c create mode 100644 src/bookmarks/sql/src/test.c create mode 100644 src/bookmarks/sql/src/testMakeDatabase.c create mode 100644 src/bookmarks/sql3/COPYING create mode 100644 src/bookmarks/sql3/Makefile create mode 100644 src/bookmarks/sql3/include/engine_bookmark.h create mode 100644 src/bookmarks/sql3/src/engine_bookmark.c create mode 100644 src/bookmarks/sql3/src/test.c create mode 100644 src/bookmarks/sql3/src/testMakeDatabase.c create mode 100644 src/bookmarks/xdxf/COPYING create mode 100644 src/bookmarks/xdxf/Makefile create mode 100644 src/bookmarks/xdxf/include/engine_bookmark.h create mode 100644 src/bookmarks/xdxf/src/engine_bookmark.c create mode 100644 src/bookmarks/xdxf/src/engine_bookmark_old.c create mode 100644 src/bookmarks/xdxf/src/test.c create mode 100644 src/bookmarks/xdxf/src/test1.c create mode 100644 src/bookmarks/xdxf/src/test2.c create mode 100644 src/bookmarks/xdxf/src/testMakeDatabase.c create mode 100644 src/dbus_wrapper/COPYING create mode 100644 src/dbus_wrapper/Doxyfile create mode 100644 src/dbus_wrapper/Makefile create mode 100644 src/dbus_wrapper/src/ws_dbus.c create mode 100644 src/gui/include/pc-instances.h create mode 100644 src/gui/include/ws_gui.h create mode 100644 src/gui/include/ws_gui_callbacks.h create mode 100644 src/gui/include/ws_gui_layout.h create mode 100644 src/gui/makefile create mode 100644 src/gui/src/pc-instances.c create mode 100644 src/gui/src/ws_gui.c create mode 100644 src/gui/src/ws_gui_callbacks.c create mode 100644 src/gui/src/ws_gui_layout.c create mode 100644 src/manager/COPYING create mode 100644 src/manager/Makefile create mode 100644 src/manager/commit create mode 100644 src/manager/include/pc-instances.h create mode 100644 src/manager/include/untar.h create mode 100644 src/manager/include/ws_manager.h create mode 100644 src/manager/include/ws_mng_bookmarks_utils.h create mode 100644 src/manager/include/ws_mng_callbacks.h create mode 100644 src/manager/include/ws_mng_dictionary_utils.h create mode 100644 src/manager/include/ws_mng_gconf_utils.h create mode 100644 src/manager/include/ws_mng_searching_threads.h create mode 100644 src/manager/include/ws_mng_threads_utils.h create mode 100644 src/manager/src/untar.c create mode 100644 src/manager/src/whitestork.c create mode 100644 src/manager/src/ws_manager.c create mode 100644 src/manager/src/ws_mng_bookmarks_utils.c create mode 100644 src/manager/src/ws_mng_callbacks.c create mode 100644 src/manager/src/ws_mng_dictionary_utils.c create mode 100644 src/manager/src/ws_mng_gconf_utils.c create mode 100644 src/manager/src/ws_mng_searching_threads.c create mode 100644 src/manager/src/ws_mng_threads_utils.c create mode 100644 src/manager_copy/COPYING create mode 100755 src/manager_copy/bin/WhiteStorkManager create mode 100644 src/manager_copy/include/pc-instances.h create mode 100644 src/manager_copy/include/untar.h create mode 100644 src/manager_copy/include/ws_manager.h create mode 100644 src/manager_copy/makefile create mode 100644 src/manager_copy/src/pc-instances.c create mode 100644 src/manager_copy/src/untar.c create mode 100644 src/manager_copy/src/whitestork.c create mode 100644 src/manager_copy/src/ws_manager.c create mode 100755 src/plugins/stardict/COPYING create mode 100755 src/plugins/stardict/Makefile create mode 100755 src/plugins/stardict/doc/DICTFILE_FORMAT create mode 100644 src/plugins/stardict/include/data.h create mode 100644 src/plugins/stardict/include/defs.h create mode 100644 src/plugins/stardict/include/dictP.h create mode 100644 src/plugins/stardict/include/dictd.h create mode 100644 src/plugins/stardict/include/dictzip.h create mode 100755 src/plugins/stardict/include/engine API.h create mode 100755 src/plugins/stardict/include/engine_stardict.h create mode 100644 src/plugins/stardict/include/maa.h create mode 100644 src/plugins/stardict/precompiled/arm/data.o create mode 100644 src/plugins/stardict/precompiled/arm/debug.o create mode 100644 src/plugins/stardict/precompiled/arm/error.o create mode 100644 src/plugins/stardict/precompiled/arm/hash.o create mode 100644 src/plugins/stardict/precompiled/arm/log.o create mode 100644 src/plugins/stardict/precompiled/arm/memory.o create mode 100644 src/plugins/stardict/precompiled/arm/prime.o create mode 100644 src/plugins/stardict/precompiled/arm/stack.o create mode 100644 src/plugins/stardict/precompiled/arm/string.o create mode 100644 src/plugins/stardict/precompiled/arm/xmalloc.o create mode 100644 src/plugins/stardict/precompiled/i686/data.o create mode 100644 src/plugins/stardict/precompiled/i686/debug.o create mode 100644 src/plugins/stardict/precompiled/i686/error.o create mode 100644 src/plugins/stardict/precompiled/i686/hash.o create mode 100644 src/plugins/stardict/precompiled/i686/log.o create mode 100644 src/plugins/stardict/precompiled/i686/memory.o create mode 100644 src/plugins/stardict/precompiled/i686/prime.o create mode 100644 src/plugins/stardict/precompiled/i686/stack.o create mode 100644 src/plugins/stardict/precompiled/i686/string.o create mode 100644 src/plugins/stardict/precompiled/i686/xmalloc.o create mode 100755 src/plugins/stardict/src/engine_stardict.c create mode 100755 src/plugins/stardict/src/test.c create mode 100644 src/plugins/stardict/test_dictsip/data.c create mode 100644 src/plugins/stardict/test_dictsip/data.h create mode 100644 src/plugins/stardict/test_dictsip/dictd.c create mode 100644 src/plugins/stardict/test_dictsip/dictd.h create mode 100644 src/plugins/stardict/test_dictsip/dictzip.c create mode 100644 src/plugins/stardict/test_dictsip/dictzip.h create mode 100644 src/plugins/xdxf/COPYING create mode 100755 src/plugins/xdxf/Makefile create mode 100644 src/plugins/xdxf/include/engine_xdxf.h create mode 100644 src/plugins/xdxf/src/engine_xdxf.c create mode 100644 src/plugins/xdxf/src/test.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4c36e58 --- /dev/null +++ b/Makefile @@ -0,0 +1,335 @@ +ARCH = `arch` +REP_TAG = ../tags +REP_BRANCH = branches + +DEB_REP_DIR = www + +#declaration of directory names +BINARIES = bin +SOURCE = src +INCLUDE = include +DATA = data +PLUGINS = ${SOURCE}/plugins +XDXF_PLUGIN = ${PLUGINS}/xdxf +STARDICT_PLUGIN = ${PLUGINS}/stardict +GUI = ${SOURCE}/gui +MANAGER = ${SOURCE}/manager +DBUS = ${SOURCE}/dbus_wrapper +BOOKMARKS:=bdb +BOOKMARKS_DIR = ${SOURCE}/bookmarks/${BOOKMARKS} +DESTDIR = + +ifeq (${BOOKMARKS}, sql) + SQLITE:=-DSQLITE=0 +endif + +ifeq (${BOOKMARKS}, sql3) + SQLITE:=-DSQLITE=3 +endif + +PACKAGES = packages + +#probably trash +STARDICT = stardict +APP_NAME = whitestork + +#versions +MAJOR_VER = 1 +MINOR_VER = 0 +RELEASE_MAJOR_VER = 1 +RELEASE_MINOR_VER = 0 +RELEASE_PATCH_VER = 1 +PACK_VER = 0 +FRM_VER = 0.1 + +# VERSION_FILE = ./${INCLUDE}/ws_version.h + +#package structure +GUI_PACK_NAME = whitestorkgui +MNG_PACK_NAME = whitestork +PLUGINS_PACK_NAME = whitestorkplugins +BOOKMARKS_PACK_NAME = whitestorkbookmarks +META_PACK_NAME = whitestorkdictionary + +GUI_EXECUTABLE = ${BINARIES}/WhiteStork +GUI_SERVICEFILE = org.maemo.WhiteStorkGui.service +GUI_DIRS = ${DESTDIR}/usr/bin ${DESTDIR}/usr/share/applications/hildon ${DESTDIR}/usr/share/pixmaps ${DESTDIR}/usr/share/mis ${DESTDIR}/usr/share/dbus-1/services ${DESTDIR}/usr/share/locale +#${DESTDIR}/usr/share/doc/whitestorkgui +GUI_DBUS = ${DATA}/other/${GUI_SERVICEFILE} +GUI_ICONS = ${DATA}/icons/whitestork_icon.png ${DATA}/icons/whitestork.png ${DATA}/icons/ws_top.png ${DATA}/icons/ws_warning_icon.png ${DATA}/icons/qgn_indi_search_whitestork.png ${DATA}/icons/ws_tra.png +GUI_LOCALE = ${DATA}/locale/out/ +GUI_DOC = ${DATA}/docs/${GUI_PACK_NAME}/ +GUI_OTHER = ${DATA}/other/whitestork.desktop +GUI_MIS = ${DATA}/mis/whitestork-search.xml + +MNG_EXECUTABLE = ${BINARIES}/WhiteStorkManager +MNG_SERVICEFILE = org.maemo.WhiteStorkManager.service +MNG_LIB = ${BINARIES}/ws_bookmark.so +MNG_DIRS = ${DESTDIR}/usr/bin ${DESTDIR}/usr/lib/WhiteStork ${DESTDIR}/usr/share/dbus-1/services ${DESTDIR}/usr/share/WhiteStork ${DESTDIR}/usr/share/doc/${MNG_PACK_NAME} +MNG_DBUS = ${DATA}/other/${MNG_SERVICEFILE} +MNG_OTHER = ${DATA}/dictionaries +MNG_DICT1 = ${DATA}/dictionaries/StarDictSampleDict/sample.dict.dz ${DATA}/dictionaries/StarDictSampleDict/sample.idx ${DATA}/dictionaries/StarDictSampleDict/sample.ifo ${DESTDIR}/usr/share/WhiteStork/dictionaries/StarDictSampleDict/ +MNG_DICT2 = ${DATA}/dictionaries/XDXFSampleDict/dict.xdxf ${DESTDIR}/usr/share/WhiteStork/dictionaries/XDXFSampleDict/ +MNG_DICT_DIRS = ${DESTDIR}/usr/share/WhiteStork/dictionaries/StarDictSampleDict/ ${DESTDIR}/usr/share/WhiteStork/dictionaries/XDXFSampleDict/ +MNG_BOOKMARKS = ${DATA}/bookmarks/${BOOKMARKS}/* +MNG_DOC = ${DATA}/docs/${MNG_PACK_NAME}/ + +PLUGINS_LIB = ${BINARIES}/engine_*.so +PLUGINS_DIRS = ${DESTDIR}/usr/lib/WhiteStork ${DESTDIR}/usr/share/pixmaps +#${DESTDIR}/usr/share/doc/${PLUGINS_PACK_NAME} +PLUGINS_ICONS = ${DATA}/icons/engine_xdxf_icon.png +PLUGINS_DOC = ${DATA}/docs/${PLUGINS_PACK_NAME}/ + +META_DIRS = ${PACKAGES}/${META_PACK_NAME}/usr/share/doc/${META_PACK_NAME} +META_DOC = ${DATA}/docs/${META_PACK_NAME}/ + +MAIL_ADDRESS = mdictionary-devel@garage.maemo.org +LOCALEDIR=/usr/share/locale +GETTEXT_PACKAGE=whitestork +ALL_LINGUAS="en_GB" + + +ifeq (${MAKECMDGOALS}, release-package) + APP_VER = ${RELEASE_MAJOR_VER}.${RELEASE_MINOR_VER}.${RELEASE_PATCH_VER} +else + APP_VER = ${MAJOR_VER}.${MINOR_VER}.`svn info | grep "Revision:" | awk '{print $$2}'` +endif + +FILES = ${DATA}/files_debbuild +LOG_DIR = logs +LOG_CLEAN = ${LOG_DIR}/clean.log +LOG_BUILD = ${LOG_DIR}/build.log +LOG_RUN = ${LOG_DIR}/run.log +LOG_DEBS = ${LOG_DIR}/debs.log +LOG_INST = ${LOG_DIR}/install.log + +first: build + @echo -e -n "" + +tag-version: clean + @install -d ${REP_TAG}/${APP_NAME}-${APP_VER} + @tar -czf ${REP_TAG}/${APP_NAME}-${APP_VER}/${APP_NAME}-${APP_VER}.tar.gz ../trunk/* --exclude .svn + @svn add ${REP_TAG}/${APP_NAME}-${APP_VER} + @svn ci ${REP_TAG}/${APP_NAME}-${APP_VER} -m "Tagged new version: ${APP_NAME}-${APP_VER}" + +send-last: debs + @tar -czf ${APP_NAME}-${APP_VER}.tar.gz *_${APP_VER}-${PACK_VER}_${ARCH}.deb + @echo -e -n "#!/bin/bash\n\ + mutt -x -a ~/debs.log -a ~/build.log -a ~/${APP_NAME}-${APP_VER}.tar.gz -s \"[WhiteStork]: daily build - version ${APP_NAME}-${APP_VER}\" ${MAIL_ADDRESS} <~/mail.content\n\ + rm -f ~/${APP_NAME}-${APP_VER}.tar.gz\n" > mail.script + + @chmod +x mail.script + + @echo -e -n "\ + This message was generated automatically , please do not reply.\n\ + Attachment: ${APP_NAME}-${APP_VER}.tar.gz - tarball with the newest Whitestork's packages.\n\ + Attachment: build.log - logs from building binaries.\n\ + Attachment: debs.log - logs from making *.deb packages.\n\n\ + Automatic Building Framework ver: ${FRM_VER}\nCopyright 2006 ComArch S.A.\n" > mail.content + @scp ${APP_NAME}-${APP_VER}.tar.gz krzsas@localhost:~/ + @scp ${LOG_BUILD} krzsas@localhost:~/ + @scp ${LOG_DEBS} krzsas@localhost:~/ + @scp mail.script krzsas@localhost:~/ + @scp mail.content krzsas@localhost:~/ + @rm -f mail.script + @rm -f mail.content + @ssh krzsas@localhost ./mail.script + +localization: + @echo -e -n "Generating locale...\n" + @echo -e -n "Generating locale...\n" > ${LOG_BUILD} + + @./generate_locale ${DATA}/locale/ ${GUI_LOCALE} + @echo -e -n "Locale generation successfully completed...\n" + @echo -e -n "Locale generation successfully completed...\n" > ${LOG_BUILD} + +build: pre-build ${BINARIES}/ws_dbus.o ${BINARIES}/WhiteStork ${BINARIES}/WhiteStorkManager ${BINARIES}/ws_bookmark.so plugins + @echo -e -n "\nBuilding WhiteStork is finished.\n" + +pre-build: + @echo -e -n "Building WhiteStork... \n" + @echo -e -n "" > ${LOG_BUILD} + +plugins: ${BINARIES}/engine_xdxf.so ${BINARIES}/engine_stardict.so + + +${BINARIES}/WhiteStorkManager: +# update-version + @echo -e -n "**--> Compiling Manager...\n" + @echo -e -n "**--> Compiling Manager...\n" >> ${LOG_BUILD} + @make SQLITE=${SQLITE} -C ${MANAGER} >> ${LOG_BUILD} + +${BINARIES}/ws_dbus.o: + @echo -e -n "**--> Compiling D-BUS Wrapper... \n" + @echo -e -n "**--> Compiling D-BUS Wrapper... \n" >> ${LOG_BUILD} +# @cd ${DBUS} && make >> ../../${LOG_BUILD} + @make -C ${DBUS} >> ${LOG_BUILD} + +${BINARIES}/WhiteStork: +#update-version + @echo -e -n "**--> Compiling User Interface...\n" + @echo -e -n "**--> Compiling User Interface...\n" >> ${LOG_BUILD} +# @cd ${GUI} && make APP_VER=${APP_VER} >> ../../${LOG_BUILD} + @make APP_VER=${APP_VER} -C ${GUI} >> ${LOG_BUILD} + +${BINARIES}/engine_xdxf.so: +# update-version + @echo -e -n "**--> Compiling XDXF Engine...\n" + @echo -e -n "**--> Compiling XDXF Engine...\n" >> ${LOG_BUILD} +# @cd ${XDXF_PLUGIN} && make >> ../../../${LOG_BUILD} + @make -C ${XDXF_PLUGIN} >> ${LOG_BUILD} + +${BINARIES}/engine_stardict.so: +# update-version + @echo -e -n "**--> Compiling StarDict Engine...\n" + @echo -e -n "**--> Compiling StarDict Engine...\n" >> ${LOG_BUILD} +# @cd ${STARDICT_PLUGIN} && make >> ../../../${LOG_BUILD} + @make -C ${STARDICT_PLUGIN} >> ${LOG_BUILD} + +${BINARIES}/ws_bookmark.so: +# update-version + @echo -e -n "**--> Compiling Bookmarks...\n" + @echo -e -n "**--> Compiling Bookmarks...\n" >> ${LOG_BUILD} + @make -C ${BOOKMARKS_DIR} >> ${LOG_BUILD} + +clean-logs: + @echo -e -n "Cleaning all logs\n" + @rm -f ${LOG_DIR}/*.log + +clean: clean-logs + @-echo -e -n "Cleaning project directories\n" + @echo -e -n "" > ${LOG_CLEAN} + @-rm -f ${BINARIES}/* >> ${LOG_CLEAN} 2>> ${LOG_CLEAN} + @-rm -f *~ >> ${LOG_CLEAN} 2>> ${LOG_CLEAN} + @-rm -f *.deb >> ${LOG_CLEAN} 2>> ${LOG_CLEAN} + @-rm -rf ${PACKAGES}/* + @-make -C ${GUI} clean >> ${LOG_CLEAN} 2>> ${LOG_CLEAN} + @-make -C ${DBUS} clean >> ${LOG_CLEAN} 2>> ${LOG_CLEAN} + @-make -C ${XDXF_PLUGIN} clean >> ${LOG_CLEAN} 2>> ${LOG_CLEAN} + @-make -C ${STARDICT_PLUGIN} clean >> ${LOG_CLEAN} 2>> ${LOG_CLEAN} + @-cd ${MANAGER} && make clean >> ../../${LOG_CLEAN} 2>> ../../${LOG_CLEAN} + @-make -C ${MANAGER} clean >> ${LOG_CLEAN} 2>> ${LOG_CLEAN} + @find src/bookmarks/ -mindepth 1 -maxdepth 1 -type d -not -name .svn -exec make -C {} clean >> ${LOG_CLEAN} 2>> ${LOG_CLEAN} \; + @-rm -rf ${GUI_LOCALE}* + +# @-cd ${GUI} && make clean >> ../../${LOG_CLEAN} 2>> ../../${LOG_CLEAN} +# @-cd ${DBUS} && make clean >> ../../${LOG_CLEAN} 2>> ../../${LOG_CLEAN} +# @-cd ${XDXF_PLUGIN} && make clean >> ../../../${LOG_CLEAN} 2>> ../../../${LOG_CLEAN} +# @-cd ${STARDICT_PLUGIN} && make clean >> ../../../${LOG_CLEAN} 2>> ../../../${LOG_CLEAN} +# @-cd ${BOOKMARKS_DIR} && make clean >> ../../../${LOG_CLEAN} 2>> ../../../${LOG_CLEAN} + +run: clean install entries run-dict clean-temp + + +run-dict: + @run-standalone.sh WhiteStorkManager + +clean-temp: + @-fakeroot rm -rf /usr/share/WhiteStork + @-fakeroot rm -rf /usr/lib/WhiteStork + @-fakeroot rm -rf /usr/include/WhiteStork + @-fakeroot rm -f /etc/others-menu/extra_applications/0112_whitestorkgui.desktop + @-fakeroot rm -f /usr/share/applications/hildon/whitestorkgui.desktop + @-fakeroot rm -f /usr/share/pixmaps/whitestork.png + @-fakeroot rm -f /usr/share/pixmaps/whitestork_icon.png + @-fakeroot rm -f /usr/bin/WhiteStork + @-fakeroot rm -f /usr/bin/WhiteStorkManager + @-fakeroot rm -f /usr/share/applications/hildon/whitestorkgui.desktop + @-fakeroot rm -f /usr/lib/WhiteStork/engine_xdxf.so + @-fakeroot rm -f /usr/lib/WhiteStork/engine_stardict.so + +# gconftool-2 --recursive-unset /apps/maemo/WhiteStork + +install-manager: localization ${BINARIES}/ws_dbus.o ${BINARIES}/ws_bookmark.so ${BINARIES}/WhiteStorkManager + @install -d ${MNG_DIRS} + @cp ${MNG_EXECUTABLE} ${DESTDIR}/usr/bin + @cp ${MNG_LIB} ${DESTDIR}/usr/lib/WhiteStork + @cp ${MNG_DBUS} ${DESTDIR}/usr/share/dbus-1/services + @find ${MNG_DOC} -type f -not -path *.svn* -exec cp {} ${DESTDIR}/usr/share/doc/${MNG_PACK_NAME} \; + +# @install -d ${MNG_DICT_DIRS} +# @cp ${MNG_DICT1} +# @cp ${MNG_DICT2} + + @install -d ${DESTDIR}/usr/share/WhiteStork/dictionaries/bookmarks + @cp -rf ${MNG_BOOKMARKS} ${DESTDIR}/usr/share/WhiteStork/dictionaries/bookmarks + +install-gui: ${BINARIES}/ws_dbus.o ${BINARIES}/WhiteStork + @install -d ${GUI_DIRS} + @cp ${GUI_EXECUTABLE} ${DESTDIR}/usr/bin + @cp ${GUI_ICONS} ${DESTDIR}/usr/share/pixmaps + @cp ${GUI_DBUS} ${DESTDIR}/usr/share/dbus-1/services + @cp ${GUI_OTHER} ${DESTDIR}/usr/share/applications/hildon + @cp ${GUI_MIS} ${DESTDIR}/usr/share/mis + @cp -a ${GUI_LOCALE}* ${DESTDIR}/usr/share/locale/ +# @find ${GUI_DOC} -type f -not -path *.svn* -exec cp {} ${DESTDIR}/usr/share/doc/${GUI_PACK_NAME} \; + +install-plugins: plugins + @install -d ${PLUGINS_DIRS} + @cp ${PLUGINS_LIB} ${DESTDIR}/usr/lib/WhiteStork + @cp ${PLUGINS_ICONS} ${DESTDIR}/usr/share/pixmaps + @install -d ${MNG_DICT_DIRS} + @cp ${MNG_DICT1} + @cp ${MNG_DICT2} +# @find ${PLUGINS_DOC} -type f -not -path *.svn* -exec cp {} ${DESTDIR}/usr/share/doc/${PLUGINS_PACK_NAME} \; + +install: install-manager install-gui install-plugins + @echo -e "\n\nIf you are installing whitestork, please run 'make entries', before running the application ( not as root )\n\n" + +entries: + gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/StarDictSampleDict/name "Polish - English Sample Dictionary" + gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/StarDictSampleDict/path "/usr/share/WhiteStork/dictionaries/StarDictSampleDict" + gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/StarDictSampleDict/active true + gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/StarDictSampleDict/optimized false + gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/XDXFSampleDict/name "English - Polish Sample Dictionary" + gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/XDXFSampleDict/path "/usr/share/WhiteStork/dictionaries/XDXFSampleDict" + gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/XDXFSampleDict/active true + gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/XDXFSampleDict/optimized false + + gconftool-2 --type string --set /apps/maemo/WhiteStork/Engines/bookmarks/path "/usr/lib/WhiteStork/ws_bookmark.so" + gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/bookmarks/name "Bookmarks" + gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/bookmarks/path "/usr/share/WhiteStork/dictionaries/bookmarks" + gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/bookmarks/active false + gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/bookmarks/optimized true + chmod -R 0777 /usr/share/WhiteStork/dictionaries + + gconftool-2 --type string --set /apps/maemo/WhiteStork/Engines/xdxf/path "/usr/lib/WhiteStork/engine_xdxf.so" + gconftool-2 --type string --set /apps/maemo/WhiteStork/Engines/stardict/path "/usr/lib/WhiteStork/engine_stardict.so" + +# maemo-select-menu-location whitestork.desktop + + +install_deb: clean-inst-log uninstall eng-deb-i mng-deb-i gui-deb-i + @echo -e -n "All packages have been installed/reinstalled.\n" + +clean-inst-log: + @echo -n "" > ${LOG_INST} + +uninstall: + @-fakeroot dpkg --purge whitestork +# @-fakeroot dpkg --purge whitestorkdictionary + +display: access + @fakeroot su ${USER} -c 'af-sb-init.sh start' + +display-s: access + @fakeroot su ${USER} -c 'af-sb-init.sh stop' + +display-r: access + @fakeroot su ${USER} -c 'af-sb-init.sh restart' + +access: + @fakeroot chmod 0777 /var/run + +release-package: clean debs meta-package + @echo "Release package generation successfully completed" + +snapshot: tag-version send-last + +repo: release-package meta-package + + @rm -rf ${DEB_REP_DIR} + @./generate_repo ${DEB_REP_DIR} + +package: clean + dpkg-buildpackage -rfakeroot diff --git a/README b/README new file mode 100644 index 0000000..9eb335c --- /dev/null +++ b/README @@ -0,0 +1,48 @@ +WhiteStork Multilingual Dictionary ver. 0.1.0 ALPHA + + + +What is WhiteStork Multilingual Dictionary +------------------------------------------ +WhiteStork is a multilingual dictionary enabling its users to use many dictionary formats. Our final goal is to use many search engines so that different file formats could be used. They will be in a form of dynamically loadable modules. For now however, we have limited the project to one engine for the XDXF format. The application consists of four modules: +- GUI - written using GTK+ Hildon, GPL License +- Engine - XDXF format parser, GPL license +- Manager - thread management and GUI starting, GPL license +- D-BUS wrapper - communication between GUI and Manager, LGPL license. + +Compilation +----------- + +In order to compile this application go to the WhiteStork/trunk directory and run the following command: + +make clean && make + +However, it is important to put out, that this will only compile the program. You won't be able to run it. Read the Installation section for information on how to install WhiteStork on your system. + +Installation +------------ + +The first thing to do, is setting an environment variable called REP_LOCATION, to match the directory containing local svn repository. This should be done in the following way: + +export REP_LOCATION = /local/svn/repository + +In order to install the program, issue the following command: + +make debs && make debs-i + +These lines, compile the source code, create a debian package and install it onto your system. + +Running +------- + +After installation is successful, there should a WhiteStork entry in the Extras submenu. All you have to do now is start it. Please refer to the WhiteStork User Interface Specification for hints on how to use our dictionary. It is available under this URL: https://garage.maemo.org/docman/?group_id=58 +The package contains two dictionaries, so you can start using our app right away. + +Should there be any problems, please contact one of our developers via garage.maemo.org. + + +Have fun using our application + + +The WhiteStork Multilingual dictionary developer's + diff --git a/add_dict b/add_dict new file mode 100755 index 0000000..7f0ad71 --- /dev/null +++ b/add_dict @@ -0,0 +1,23 @@ +#!/bin/bash + +if [ -z $1 ]; then + echo -e "\n* AddDict utility - tool for adding dictionaries to GConf *\n" + echo -e "Usage:\n\n./add_dict \n" + +else + if [ -z $2 ]; then + echo "Dictionary name wasn't specified. Run without parameters to get help." + else + if [ -e $1 ]; then + gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/$2/name "$2" + gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/$2/path "`pwd`/$1" + gconftool-2 --type boolean --set /apps/maemo/WhiteStork/Dictionaries/$2/active false + gconftool-2 --type boolean --set /apps/maemo/WhiteStork/Dictionaries/$2/optimized false + gconftool-2 -R /apps/maemo/WhiteStork/Dictionaries/$2 + else + echo "Dictionary file couldn't be found. Run without parameters to get help." + + fi + + fi +fi diff --git a/data/bookmarks/bdb/bm_trans.db b/data/bookmarks/bdb/bm_trans.db new file mode 100644 index 0000000000000000000000000000000000000000..7abe57a73c139b1959fe8851353254f053fa1320 GIT binary patch literal 8192 zcmeI#yA6OK6a~=dug1#S6r8A3o!SV41c0^CsXPRDsHF-6H*w>$e=oCF9EAV7cs z0RjXF5FkK+z%K-bZi=z=Epp1KyHp7fAV7cs0RjXF5FkK+0D(^l%;mLpwLBmH3rWrb AQIGPeOjIx-(V*| zfB*pk1PBlyK!5-N0t9{`P-M3#V;fhh~7cKS#1poj5 literal 0 HcmV?d00001 diff --git a/data/bookmarks/sql/ws_bookmarks b/data/bookmarks/sql/ws_bookmarks new file mode 100644 index 0000000000000000000000000000000000000000..183c23bcbebd1e1e7a6e2f5d95504fdd32c9fe30 GIT binary patch literal 3072 zcmdPWQV7Y&ELKR%%t=*9&d)1J%*-oRNX%0R4)n<^NmVe?GgL@PEJ;jCEKXI>(qhmk zeSC`n3W9(%3yd>LkA}c#2n@*(;9!^lb~hw1moqdlFfg+5NUCX+1M_`ODnm(8VqS4h zVo7FxUNI`in87*7)iK0XA;i(i$5jDYp+;tkf~Q}ItGjEELO_tGuVYZ8g12j=jzW2U xQHnx{Yea|+vU;$HCWBJ}^NB0^Lx8*x0089(J5~Sy literal 0 HcmV?d00001 diff --git a/data/bookmarks/sql3/ws_bookmarks3 b/data/bookmarks/sql3/ws_bookmarks3 new file mode 100644 index 0000000000000000000000000000000000000000..21a9e508885c7495c5860ea823cc5c5b4b39d59c GIT binary patch literal 2048 zcmWFz^vNtqRY=P(%1ta$FlJz3U}R))P*7lCU|>vFd72bL!g+EU0hX_u~D-mF)1gtq$n}3I47|rGe55wna$)JFXF2so?DzsiRPyUzDN{;u;a6gRCAbq6x~ID7hND+eSr4 MLtr!nhG7T*0J3H+umAu6 literal 0 HcmV?d00001 diff --git a/data/bookmarks/xdxf/ws_bookmarks.cache b/data/bookmarks/xdxf/ws_bookmarks.cache new file mode 100644 index 0000000..e69de29 diff --git a/data/bookmarks/xdxf/ws_bookmarks.xdxf b/data/bookmarks/xdxf/ws_bookmarks.xdxf new file mode 100644 index 0000000..d34ed91 --- /dev/null +++ b/data/bookmarks/xdxf/ws_bookmarks.xdxf @@ -0,0 +1,7 @@ + + + +WhiteStork Bookmarks +Version: 1.0 + + \ No newline at end of file diff --git a/data/dictionaries/StarDictSampleDict/sample.dict.dz b/data/dictionaries/StarDictSampleDict/sample.dict.dz new file mode 100644 index 0000000..f6d5541 --- /dev/null +++ b/data/dictionaries/StarDictSampleDict/sample.dict.dz @@ -0,0 +1 @@ +Thank you very much.WhitestorkBe careful!I would like a ticket to...I would like to change dollars.I think I am lost.What town is this?What?traveller's checksJunefortyfourteenfourfour thousandfour hundredThursdayfourthCan I get there on foot?Is there a taxi standby nearby?Is there a currency exchange office nearby?Is there a sleeping car on the train?Do you have a map of the city?May we have an extra bed?Can I pay with my credit card?Could you help me?Could you show me this on the map, please?Do you speak English?Why?Good-bye.Good night.(Goodbye at night time)Good evening.Okay.seconda lot ofmuchtwotwo thousandtwentytwenty-onetwelvetwo hundredtwicetenthtenten percentten thousandninthnineteenninenine thousandninetynine hundreddayGood day.Good morning.todayThank you.Where is the nearest...Where is the nearest bank?Where is... ?Where?DecemberHow much do I owe you?How much is it per night?How much is the fare?How old are you?What is your name?How late it is?How do I get to this address?How far is it?How?Which line goes to...?oneelevena thirdautumnIt is two in the afternoon.It is 4:30 am.It is two o'clock.It is 6:15 pm.It is one o'clock.It is three in the afternoon.It is 3:40 am.It is three o'clock.It is one in the afternoon.tomorrowWhen does it leave?When does it arrive?When?fewblanketsupperWho?What time is it?AprilsummerdoctorleftJulyNovemberFebruaryMayMy name is...I have a reservation.MarchDo you have any vacancies?Can we switch rooms?Can you show me the room?on the cornerI do not speak Polish.I do not understand.No.SundaynightsdinnerOf course.eighteight thousandeightyeighteeneight hundredOctoberplatformfirstFridayfifthfifteenfivefive minutes agofive thousandfiftyfive hundreddouble bedroomHelp!MondayRepeat, please.halfnoonrightstraight aheadPlease tell me when to get off.The bill, please.Please call me a taxi.Please speak more slowly.Please.You are welcome.private bathExcuse me.Excuse me.I am sorry.bus stationtram stationmidnightlateronceKeep the change.roll of toilet paperI understand a little.bath towelssevenseven thousandseventyseventeenseven hundredAugustseventhSaturdaytrain stationsubway stationone hundredStop!Januarysixteensixsix thousandsixtysix hundredsixthYes.nowtracksomethirdthreethree thousandthirtythirteenthree hundredone thousandWatch out!earlieryesterdaymanyspringHello.soonSeptemberAll aboard.TuesdayzeroThat's right.Agreed.wintereightha quarterI am in a hurry.breakfastWednesday \ No newline at end of file diff --git a/data/dictionaries/StarDictSampleDict/sample.idx b/data/dictionaries/StarDictSampleDict/sample.idx new file mode 100644 index 0000000000000000000000000000000000000000..e140e95d53b217bd15377dd90514ae4fd5254c48 GIT binary patch literal 4539 zcmZu#Yls|K6;8UVs;g(FCzCjdn~h0o7ZsyR6kSw&;F<(>O-Kwe?n->X?XGL5y1MH& zRn-<%po`;%s0jXW(VdN`h_64o>VQZbbY;4IfC`EaSV0j4Mg5~cRL~!O-?`P9o^=C# zQs+D8zRo?bJ7-iHRwf9mXu26s2Gh;c`|5w|XG||r3AuIrmd;FXgtOa$$@0|9wv+N6 zN>1RneD*pNXB*ve6m+AZ&V$gLJ}vW{g80~ixF|=FPNL~es0>wFiqbhKojiNJ?5ZHc zE`q8*=|-~+JrZdT(nDuWkei@V!6;H$Zr%iJ-^2>!`zF5KUZvwG7@IKN*}?`jl|Du# z2+|_boN3=@@N;@qu5s*0&u;Z1qMyeP?zQ;hurUUDO!p zEEjoq7-g}+@v?kpYXB(DcD4!~%lZES^^<$lW0mA44QOzcltH0}lbovi4}!dGk7}X% zCJC}~9I0VaiqadP^dc&aR91nEu}Lw#5;0GCLd5U{Jt~87YG4rFYN+zq6grq~@DgG< z&HhKBe{`opz%@xsY$+mO2i;@{yO2IqtY&E2>L(!}?o?={{Ha0TGpmqnA)dW#^ODAWlj z;TlU2?Rt5G4hd}=3v}qlqae#+F^N-?ClU&cj{Hf1(FXgvQpHOio?5{dWbaVXurtAwEeeYg1< zkdENOGP8R9bi(!IJk9e!{I?A4>Uso6O>D?FuRwBylGtQbJ{eFYMCib~Wv=UxAKfD# z!=VSN3Pt=uh!0aN8Dpp<*)%^1bnU!~EsEKq5zHY2z68-BipEG3w-XZ#5CdWq5q}%v z0~F)FHeq_C)&w8O?m@1TK!vH!MDd4EJWfSKe5i)nrkv&<0j~lU9fq_6Mg_wN@f*aG zG~)@SPKm}pp>bp$Ce8}Drf_$vfpY+uXHAmh;HY?<^e{*ZIl8v5^8#v}XU?vx3HD8w zaqa~y3IKKh$FGNV{ zfe8nCwjIv4rF1yIhva!y0{+)Nvd0Vxh@o8wRi-uIW-O>mh zbP!_VuS4f3!ZI~|wo~qpK{}U^oKR<(dRZOEhNY30?EV_$2*s(XCRkEBH1}^n*MU-n zcebyIszJvd@^ZW;39<-li`OPG-AL@_9U%ACUR4&6bX_t7FLOzpol@SKE8JpY_g)Bi zRbVbO&*|PPIiwDhc^~J!7N9Sn&GFs?06JqeyUnp_5;07?iy*DBPEA7YDu`dll2pid z0dNsTH*8Di$Xkz6;5Lv6*cc=}Wwyaz65t5OZ+Y&jm@9#E$nXa4sj1F!P=P zyL#EqXInZ%BoBvvq0j$ODo~cBznCcjdeN!PRD_o1pyFgin6KSbF{ib@3gTSB8v`c@hp0f2?%J?zeFLJk)F9Ue zWA@7F1oafv6g@e*U=IF1$oiE!?gQlc-u2qFyx}A1bhB3>l-PW>{tB{;auw@>$U#F_+EY+^8G!OQ0!)Ti5G%h z_PqdFS*5du?aIl4(TO>Tci*h}MJxCW{*_v=#|$5Wz^w)Ki9ZZzIm62WtK-xE1XZpo zi3I-%Fbi-*j8);(5^wQoB;uMjAvB|n1-Xjs7&Do*<#0H;87!cpY5+AJ{b zN6@8*OcmqZ+}1t;$#MasNfK|9H45@x=Bea?_hdgx*imM*Av|_UuXcZpMdpB%Q9z%5H9r=D-eZPHoeh+Ou0J KR^r$DNd5=Brswql literal 0 HcmV?d00001 diff --git a/data/dictionaries/StarDictSampleDict/sample.ifo b/data/dictionaries/StarDictSampleDict/sample.ifo new file mode 100644 index 0000000..a37e79e --- /dev/null +++ b/data/dictionaries/StarDictSampleDict/sample.ifo @@ -0,0 +1,6 @@ +StarDict's dict ifo file +version=2.4.2 +wordcount=209 +idxfilesize=4539 +bookname=sample +sametypesequence=m diff --git a/data/dictionaries/XDXFSampleDict/dict.xdxf b/data/dictionaries/XDXFSampleDict/dict.xdxf new file mode 100644 index 0000000..71717ee --- /dev/null +++ b/data/dictionaries/XDXFSampleDict/dict.xdxf @@ -0,0 +1,214 @@ + + + English - Polish dictionary + Sample dictionary with some usefull expressions. Any suggestions? Please conntact marcin.biedron@comarch.pl. This file is part of WhiteStork application. Copyright 2007, ComArch S.A. All rights reserved. + a lot of - dużo + a quarter - ćwiartka + a third - jedna trzecia + Agreed. - Zgoda. + All aboard. - Wsiadać proszę. + April - kwiecień + August - sierpień + autumn - jesień + bath towels - ręczniki + Be careful! - Bądź ostrożny! + blanket - koc + breakfast - śniadanie + bus station - przystanek autobusowy + Can I get there on foot? - Czy dojdę tam na pieszo? + Can I pay with my credit card? - Czy można płacić kartą (kredytową)? + Can we switch rooms? - Możemy zamienić pokoje? + Can you show me the room? - Możesz pokazać mi pokój? + Could you help me? - Czy mógłbyś mi pomóc? + Could you show me this on the map, please? - Czy mógłbyś pokazać mi to miejsce na mapie? + day - dzień + December - grudzień + dinner - obiad + Do you have a map of the city? - Czy masz mapę miasta? + Do you have any vacancies? - Masz wolne pokoje? + Do you speak English? - Czy mówisz po angielsku? + doctor - lekarz + double bed - podwójne łóżko + earlier - wcześniej + eight - osiem + eight hundred - osiemset + eight thousand - osiem tysięcy + eighteen - osiemnaście + eighth - ósmy + eighty - osiemdziesiąt + eleven - jedenaście + Excuse me. - Przepraszam. + Excuse me. - Przepraszam. + February - luty + few - kilka + fifteen - piętnaście + fifth - piąty + fifty - pięćdziesiąt + first - pierwszy + five - pięć + five hundred - pięćset + five minutes ago - pięć minut temu + five thousand - pięć tysiące + forty - czterdzieści + four - cztery + four hundred - czterysta + four thousand - cztery tysiące + fourteen - czternaście + fourth - czwarty + Friday - piątek + Good day. - Dzień dobry. + Good evening. - Dobry wieczór. + Good morning. - Dzień dobry. + Good night.(Goodbye at night time) - Dobranoc. + Good-bye. - Do widzenia. + half - połowa + Hello. - Witam. + Help! - Pomocy! + How do I get to this address? - Jak się dostanę pod ten adres? + How far is it? - Jak to daleko? + How late it is? - Jak późno już jest? + How much do I owe you? - Ile jestem winny? + How much is it per night? - Ile kosztuje jedna noc? + How much is the fare? - Ile kosztuje przejazd? + How old are you? - Ile masz lat? + How? - Jak? + I am in a hurry. - Śpieszy mi się. + I am sorry. - Przykro mi. + I do not speak Polish. - Nie mówię po polsku. + I do not understand. - Nie rozumiem. + I have a reservation. - Mam rezerwację + I think I am lost. - Chyba się zgubiłem. + I understand a little. - Rozumiem trochę. + I would like a ticket to... - Chciałbym bilet do... + I would like to change dollars. - Chciałbym wymienić dolary. + Is there a currency exchange office nearby? - Czy jest tam kantor wymiany walut? + Is there a sleeping car on the train? - Czy jest tam wagon sypialny? + Is there a taxi standby nearby? - Czy jest tam blisko postój taksówek? + It is 3:40 am. - Jest trzecia czterdzieści. + It is 4:30 am. - Jest czwarta czterdzieści. + It is 6:15 pm. - Jest osiemnasta piętnaście. + It is one in the afternoon. - Jest trzynasta. + It is one o'clock. - Jest pierwsza. + It is three in the afternoon. - Jest piętnasta. + It is three o'clock. - Jest trzecia. + It is two in the afternoon. - Jest czternasta. + It is two o'clock. - Jest druga. + January - styczeń + July - lipiec + June - czerwiec + Keep the change. - Reszta dla ciebie. + later - później + left - lewo + many - wiele + March - marzec + May - maj + May we have an extra bed? - Czy możemy prosić dodatkowe łóżko? + midnight - północ + Monday - poniedziałek + much - dużo + My name is... - Mam na imię... + nights - noce + nine - dziewięć + nine hundred - dziewięćset + nine thousand - dziewięć tysięcy + nineteen - dziewiętnaście + ninety - dziewięćdziesiąt + ninth - dziewiąty + No. - Nie. + noon - południe + November - listopad + now - teraz + October - październik + Of course. - Oczywiście. + Okay. - Dobrze. + on the corner - na rogu + once - raz + one - jeden + one hundred - sto + one thousand - tysiąc + platform - peron + Please call me a taxi. - Proszę wezwać mi taksówkę. + Please speak more slowly. - Proszę, mów wolniej. + Please tell me when to get off. - Proszę mi powiedzieć gdzie mam wysiąść. + Please. - Proszę. + private bath - prywata łazienka + Repeat, please. - Powtórz proszę. + right - prawo + roll of toilet paper - rolka papieru toaletowego + room - pokój + Saturday - sobota + second - drugi + September - wrzesień + seven - siedem + seven hundred - siedemset + seven thousand - siedem tysięcy + seventeen - siedemnaście + seventh - siódmy + seventy - siedemdziesiąt + six - sześć + six hundred - sześćset + six thousand - sześć tysięcy + sixteen - szesnaście + sixth - szósty + sixty - sześćdziesiąt + some - trochę + soon - wkrótce + spring - wiosna + Stop! - Stop! + straight ahead - prosto + subway station - stacja metra + summer - lato + Sunday - niedziela + supper - kolacja + ten - dziesięć + ten percent - dziesięć procent + ten thousand - dziesięć tysięcy + tenth - dziesiąty + Thank you very much. - Bardzo dziękuję. + Thank you. - Dziękuję. + That's right. - Zgadza się. + The bill, please. - Proszę o rachunek. + third - trzeci + thirteen - trzynaście + thirty - trzydzieści + three - trzy + three hundred - trzysta + three thousand - trzy tysiące + Thursday - czwartek + today - dzisiaj + tomorrow - jutro + track - tor + train station - stacja kolejowa + tram station - przystanek tramwajowy + traveller's checks - czeki podróżne + Tuesday - wtorek + twelve - dwanaście + twenty - dwadzieścia + twenty-one - dwadzieścia jeden + twice - dwukrotnie + two - dwa + two hundred - dwieście + two thousand - dwa tysiące + Watch out! - Uważaj! + Wednesday - środa + What is your name? - Jak masz na imię? + What time is it? - Która godzina? + What town is this? - Co to za miasto? + What? - Co? + When does it arrive? - Kiedy przyjeżdża? + When does it leave? - Kiedy odjeżdża? + When? - Kiedy? + Where is the nearest bank? - Gdzie jest najbliższy bank? + Where is the nearest... - Gdzie jest najbliższa... + Where is... ? - Gdzie jest... ? + Where? - Gdzie? + Which line goes to...? - Jaka linia kursuje do...? + Whitestork - Bocian + Who? - Kto? + Why? - Dlaczego? + winter - zima + Yes. - Tak. + yesterday - wczoraj + You are welcome. - Proszę. + zero - zero + \ No newline at end of file diff --git a/data/docs/whitestork/changelog b/data/docs/whitestork/changelog new file mode 100644 index 0000000..607b5ab --- /dev/null +++ b/data/docs/whitestork/changelog @@ -0,0 +1,5 @@ +whitestork (0.1.0) + + * Testing changelog. + * whitestork + -- author 2006-09-07 diff --git a/data/docs/whitestork/changelog.Debian b/data/docs/whitestork/changelog.Debian new file mode 100644 index 0000000..7bc6702 --- /dev/null +++ b/data/docs/whitestork/changelog.Debian @@ -0,0 +1,2 @@ +whitestork Debian maintainer and upstream author are identical. +Therefore see also normal changelog file for Debian changes. \ No newline at end of file diff --git a/data/docs/whitestork/copyright b/data/docs/whitestork/copyright new file mode 100644 index 0000000..e455ce8 --- /dev/null +++ b/data/docs/whitestork/copyright @@ -0,0 +1,3 @@ +whitestork + +All programs are either under the GPL or LGPL. The complete text of the GPL and LGPL licenses can be found in the /usr/share/common-licenses/GPL and /usr/share/common-licenses/LGPL files. \ No newline at end of file diff --git a/data/docs/whitestorkdictionary/changelog b/data/docs/whitestorkdictionary/changelog new file mode 100644 index 0000000..8b4e027 --- /dev/null +++ b/data/docs/whitestorkdictionary/changelog @@ -0,0 +1,5 @@ +enginexdxf (0.1.0) + + * Testing changelog. + * enginexdxf + -- author 2006-09-07 diff --git a/data/docs/whitestorkdictionary/changelog.Debian b/data/docs/whitestorkdictionary/changelog.Debian new file mode 100644 index 0000000..8023d75 --- /dev/null +++ b/data/docs/whitestorkdictionary/changelog.Debian @@ -0,0 +1 @@ +See changelog. \ No newline at end of file diff --git a/data/docs/whitestorkdictionary/copyright b/data/docs/whitestorkdictionary/copyright new file mode 100644 index 0000000..7b22cfd --- /dev/null +++ b/data/docs/whitestorkdictionary/copyright @@ -0,0 +1,3 @@ +WhiteStork Dictionary + +All programs are either under the GPL or LGPL. The complete text of the GPL and LGPL licenses can be found in the /usr/share/common-licenses/GPL and /usr/share/common-licenses/LGPL files. \ No newline at end of file diff --git a/data/docs/whitestorkgui/changelog b/data/docs/whitestorkgui/changelog new file mode 100644 index 0000000..d5c3bfd --- /dev/null +++ b/data/docs/whitestorkgui/changelog @@ -0,0 +1,5 @@ +whitestorkgui (0.1.0) + + * Testing changelog. + * whitestorkgui + -- author 2006-09-07 diff --git a/data/docs/whitestorkgui/changelog.Debian b/data/docs/whitestorkgui/changelog.Debian new file mode 100644 index 0000000..cff7f1c --- /dev/null +++ b/data/docs/whitestorkgui/changelog.Debian @@ -0,0 +1,2 @@ +whitestorkgui Debian maintainer and upstream author are identical. +Therefore see also normal changelog file for Debian changes. \ No newline at end of file diff --git a/data/docs/whitestorkgui/copyright b/data/docs/whitestorkgui/copyright new file mode 100644 index 0000000..2a3070b --- /dev/null +++ b/data/docs/whitestorkgui/copyright @@ -0,0 +1,3 @@ +whitestorkgui + +All programs are either under the GPL or LGPL. The complete text of the GPL and LGPL licenses can be found in the /usr/share/common-licenses/GPL and /usr/share/common-licenses/LGPL files. \ No newline at end of file diff --git a/data/docs/whitestorkplugins/changelog b/data/docs/whitestorkplugins/changelog new file mode 100644 index 0000000..14929fd --- /dev/null +++ b/data/docs/whitestorkplugins/changelog @@ -0,0 +1,5 @@ +whitestorkplugins (0.6.0) + + * Testing changelog. + * enginexdxf + -- author 2006-09-07 diff --git a/data/docs/whitestorkplugins/changelog.Debian b/data/docs/whitestorkplugins/changelog.Debian new file mode 100644 index 0000000..2834b45 --- /dev/null +++ b/data/docs/whitestorkplugins/changelog.Debian @@ -0,0 +1,3 @@ +whitestorkplugins +Debian maintainer and upstream author are identical. +Therefore see also normal changelog file for Debian changes. \ No newline at end of file diff --git a/data/docs/whitestorkplugins/copyright b/data/docs/whitestorkplugins/copyright new file mode 100644 index 0000000..8c97a75 --- /dev/null +++ b/data/docs/whitestorkplugins/copyright @@ -0,0 +1,3 @@ +whitestorkplugins + +All programs are either under the GPL or LGPL. The complete text of the GPL and LGPL licenses can be found in the /usr/share/common-licenses/GPL and /usr/share/common-licenses/LGPL files. \ No newline at end of file diff --git a/data/icons/engine_xdxf_icon.png b/data/icons/engine_xdxf_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b35c0ccbc297274d74a7fd88bf6ab6906905e798 GIT binary patch literal 944 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4m>B|mLR|m<|G!|t0tN;Lp!g^l zLLqQkrT~b5kqL40X_*&C4gsTB+XczhDN3XE)M-9L@rd$YKTt zZXpn6ymYtj4^Yt4)5S5Q;#R6ZCm(|W%jJLnFBbb%lgWWfTi38x zhc}t5JrpL>Z=L$4acx4SM^(am!N2=Y=V!X|L{|4?AAZbOy^-O?ma>?7kh?rx{an^L HB{Ts5te|Jm literal 0 HcmV?d00001 diff --git a/data/icons/engine_xdxf_icon_2.png b/data/icons/engine_xdxf_icon_2.png new file mode 100644 index 0000000000000000000000000000000000000000..ec8ca10a1fd0ffc9e8aa8ac852115e18ed8712cc GIT binary patch literal 210 zcmV;@04@KCP)&kqA<->y^pMjtxC?S`58Nu?dl03Z??F6dsM(od`X2zO`OQ5Z)wyA?r^1TC8+}+Wdf67Aj{pDw M07*qoM6N<$f*G1wB>(^b literal 0 HcmV?d00001 diff --git a/data/icons/qgn_indi_search_whitestork.png b/data/icons/qgn_indi_search_whitestork.png new file mode 100644 index 0000000000000000000000000000000000000000..482de9b92fb0eead643c197695da85fd30a0e5b2 GIT binary patch literal 1563 zcmV+$2ITpPP)oe03CEi zSad^gZEa<4bO1wgWnpw>WFU8GbZ8({Xk{QrNlj4iWF>9@00nL6xjom6xsN&p27L3a@;5EuLBm07-5-2c} zMZm#Y9XPQl&?{mKXd)m86r%Cc3-Hp**@u(8ArO&}kS*E!Pd}XJ$@4$Y>F<5d$!RGN zLI8jb!vFvP0EXR;2J(O}kjvXEC z?F%$&fB5i9NlBAZIWjS^Dj+~6l`hgq$mw(jty(pI8SfQ@5JG76_C_E0kLG6xwKO-c z0AP4%2!$Ex>7gMZ*UQUM*wok<5)`D>Xkxfr_I<^U7VY1v)NGodU<)aSlneWtPc$p3Iu)(Mo3`b zuQfFQfG2%@yAl&onMf$K+wB2({Rj<>UmeTNs|yPXemHSrrH_wNq2O=bie{5Z zr5Wkz%XM}znM?q{nWCa&1qD7nK31z00AMzooA2Do5{orzwLz~JWoDXRy}EGeQf_wk z^z?L_O0{9*Mr7ZfkRZ;@wc+^M;NV?}i4KROySLZa*Vo(AbETvN)qHpScx`ocY-D6Z zT^-SvFa`z%eY$gJbWF_Cfq_RRQ=3X9Eh_^6+-+&OQCs`$*|Xp3>j(P#xA6Jqv9ZsS zlVwur`HL5qWwZErdqW6KMq@CWZMWNHQt8RULI~l-^XD_t(;o=(H|X`e=xDUKM_pYg$>nfNMx(`IVbJNfl}cjr##^_90>PY) zkGs1Wbo%qb!P&-OHXFxrqUKh8{r-LX-o1P0i(yk!QxHOn#X_f2H>_JnH2t7FmbOzE zOlEIS&jXdJyrKdCK&R7fHe2hxdsHfQ*Y4f-TU%pdW6@Rz0BF?eEquP!Y8@UL;zmXS z0N%cRYaSbm*u1&3qXWnBls$W9Pkz0!a!$Lb=x9!O_~hi|Y$GQ;oJOM&HF}*cHZD%5 z)$-!wJv}{9X5ISrR*S{$b}#aKEfEKc#X4JD{B3?dhG75z8jWVPT4hpcjzmJCP&8^a zaex5;v>MIF+qUU-I)af-tBvFFs8p)U<=UQ*@Rv%paJ%vGaU93PBO>m$v>>C?>3s9% z4N)*LF(I$2deG4!ud3R@=M#@1H7#v>Lc$k&_dZms*=+W5UBkx5$5pMZhw}1JxPnG| zF+BX|?b~08M8xYr6r)h9(ac^b8uQ}gpFVj~BbVbiKG5HPrl?3H6aoOsuU-44v~+Z2 z1jliWS}oYW|7vL|0*#DuJl^xc!5g);Gcz;l&d%hdq#sY84qCHj_LD#zQ&Lk8A33rw zHFbJ=dRgurI<1!F}?% z5piCq?%(G{M|*jA1hd%^vDj=jqZ5SB<6$(KKZ})?l48*7=Npv@1t%oDijQfNM8hRVt{8lnv zUN55C=wc)^o5kyd=Dp^BT#hVhkA3b<>^KtqfWuO??|JgxF&SA6fr7>5H<) z_r)jY+W0zg$n0l%Z@XOBhx@rsjP%bJn(Ad+R2}nj`#&gToxYbX_qAi$8@Y{ACeItC zHhK5PoqRR7Hu~1o3LE`txmRYty25ti%t6sxOWy00=;~M&U5?!GTPbK~%G(@`*j~r9 zhpTJ^CVF2{i^ysLh^4v9qYqO%R8()?5}F>%?X47RTRA(+hkx(f>+9I_ zlns`q-b@vJ$#lK^=8MRh*STkJe(Eq2+tFmR$d`4UQh!EpqxQxxDwm?4s9c&~t9&{q z``$?>6_5D$qQUM9$|hMqsyocuH*J~haf3#~2PQW}y*{~o-*|PA-Ug97Yl1_|zjTC% z-k3Cht=cB5Jl)2Z_Af=ffaFNi&mQ?J?N6&*vW(*6 z@5~LiTR(qZ+1^}rOQv+aSIWBT>P1W9UDm}%_Z$#&+poP=iWwNqJ_;Qx9G)zAv}%f) zn{=bXBc}VABG;CrYAJt^Rk`+TOIH7fb3)Ts99wcw;Ottv>ziV14N_AldWSDre`8*U z!ZvO76BlX|pE+Dw{w3VyP0FFr8_PLFoC6o=K6L;Z%*kTdsDP5Fa0s4ApYlcYC))#- Wn#7l>)uF&-%;4$j=d#Wzp$PzdphkKC literal 0 HcmV?d00001 diff --git a/data/icons/whitestork_icon.png b/data/icons/whitestork_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2c3563bdcae59e515913ebd0fbdf1d63e5b90946 GIT binary patch literal 277 zcmV+w0qXvVP)|#L{VBhDH z`KKLKLEe0ae(wcEN&N<%;K<=P#fHg2xVGqTR7_bmlQ9h|^u z)pcQhn$!QIF3d__WFZDt09AbX>DV*LAR^5R`;&WACG+--?XVD93}HuriYlZiVtc5v b_J5!o#LCw#8{S%C00000NkvXXu0mjf_N#YT literal 0 HcmV?d00001 diff --git a/data/icons/ws_top.png b/data/icons/ws_top.png new file mode 100644 index 0000000000000000000000000000000000000000..26496e93fb2cead518ba5c350d689b423811a3fb GIT binary patch literal 280 zcmeAS@N?(olHy`uVBq!ia0vp^ObiT+6F7h*12?Z)Kak=q@Q5r1@`ON`@zUM8KS04# zo-U3d6}R3VI_=l&AklC!|N6S9u(r_D)Yr!@w2FQ>k}e|br#pHNTG;!``f{91kW z56?3ziM(t7ZgsxS$>036T1r(sTlKSv=Nk*JWr-7dj(Pap_x`nRa>?_}Pd4YOuDvF7 z*JRSNb*iPIo~tf<7U_6w((F7{e6s!U?!&VWXHWCoWHMESPoIyyJ)QmhXB!}T bU;mp~W|d7vY?OU6&{qteu6{1-oD!M?A1Tfjum)5T7d%bU(&X77<%uBn*+YQhuDfySBo ztPx`nVTAz0#4rj|hKz6_Fc2Fd^dZK}M6lBrn=AtipD|qpFg_CbXSVW@$ed@L$xnGp z5ssH>u_oCz0v_CQL%_TPtYU)Xp{!$4m?yA_eb$y7l@Af;BOE~i`M+D*KdK;QP%278 zj3M5rWRp^zoPP8^oIjsk^gdnnE`D^s+&+DM=zLc?Kh?*ZntQv~=5t=$aop<(8{(JV z;@%@&a0EL#SX4&lg15=zUF3zGzFM`pGE x1Ltr`0r~rFw{lcUO0`t3t6`{kwUX(j`U@R^<1Fp7ee3`L002ovPDHLkV1ilY;}rk^ literal 0 HcmV?d00001 diff --git a/data/icons/ws_warning_icon.png b/data/icons/ws_warning_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7e4f7b6e65cb1c9ba6cb352a866e6b4f98c1b763 GIT binary patch literal 781 zcmV+o1M>WdP))bJou%8_+U_?tZk>U? z$n0*&kx+f?Q8Jk{fA?BS0lZ%CKvPp)|H{e^R@W3%u{-@%2m__Oe*k7?X4ux2Xq@$| z(jy}eFm~ews_He`=lC8U92{i-2?&S7qYaJus8)Or-phey-Joa*;h-3GP-L_$ARdoL zVlAODoAnhGWdmNG1Iv0Kiz+ydLCB|!b#pJ-*MVYWi)dHd`$vWFtXyaysN;G?$y#lZGg4F$=7ba()Zg+^rL`NE&c+invweQ zO@G, 2006. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-11-14 11:34+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Anna Gadomska \n" +"Language-Team: polish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../gui/src/ws_gui.c:49 +msgid "ws_check" +msgstr "OK" + +#: ../gui/src/ws_gui_layout.c:42 +msgid "ws_ni_welcome" +msgstr "Welcome to mDictionary!" + +#: ../gui/src/ws_gui_layout.c:174 ../gui/src/ws_gui_layout.c:351 +msgid "ws_me_search_find" +msgstr "Find" + +#: ../gui/src/ws_gui_layout.c:266 +msgid "ws_me_dictionaries" +msgstr "Dictionaries" + +#: ../gui/src/ws_gui_layout.c:268 +msgid "ws_me_bookmarks" +msgstr "Bookmarks" + +#: ../gui/src/ws_gui_layout.c:270 +msgid "ws_me_edit" +msgstr "Edit" + +#: ../gui/src/ws_gui_layout.c:272 +msgid "ws_me_view" +msgstr "View" + +#: ../gui/src/ws_gui_layout.c:274 +msgid "ws_me_search" +msgstr "Search" + +#: ../gui/src/ws_gui_layout.c:276 +msgid "ws_me_about" +msgstr "About..." + +#: ../gui/src/ws_gui_layout.c:278 +msgid "ws_me_close" +msgstr "Close" + +#: ../gui/src/ws_gui_layout.c:285 +msgid "ws_me_dictionaries_load" +msgstr "Load dictionary..." + +#: ../gui/src/ws_gui_layout.c:287 +msgid "ws_me_dictionaries_select" +msgstr "Select dictionaries..." + +#: ../gui/src/ws_gui_layout.c:289 +msgid "ws_me_dictionaries_remove" +msgstr "Remove dictionaries..." + +#: ../gui/src/ws_gui_layout.c:291 +msgid "ws_me_dictionaries_optimize" +msgstr "Optimize dictionaries..." + +#: ../gui/src/ws_gui_layout.c:303 +msgid "ws_me_bookmarks_open" +msgstr "Open Bookmarks" + +#: ../gui/src/ws_gui_layout.c:305 +msgid "ws_me_bookmarks_close" +msgstr "Close Bookmarks" + +#: ../gui/src/ws_gui_layout.c:307 +msgid "ws_me_bookmarks_add" +msgstr "Add Bookmark..." + +#: ../gui/src/ws_gui_layout.c:309 +msgid "ws_me_bookmarks_remove" +msgstr "Remove Bookmark..." + +#: ../gui/src/ws_gui_layout.c:321 +msgid "ws_me_edit_copy" +msgstr "Copy" + +#: ../gui/src/ws_gui_layout.c:323 +msgid "ws_me_edit_paste" +msgstr "Paste" + +#: ../gui/src/ws_gui_layout.c:325 +msgid "ws_me_edit_select_all" +msgstr "Select All" + +#: ../gui/src/ws_gui_layout.c:334 +msgid "ws_me_view_hide_words_list" +msgstr "Hide words list" + +#: ../gui/src/ws_gui_layout.c:336 +msgid "ws_me_view_zoom_in" +msgstr "Zoom in" + +#: ../gui/src/ws_gui_layout.c:338 +msgid "ws_me_view_zoom_out" +msgstr "Zoom out" + +#: ../gui/src/ws_gui_layout.c:340 +msgid "ws_me_view_fullscreen" +msgstr "Full screen" + +#: ../gui/src/ws_gui_layout.c:353 +msgid "ws_me_search_find_next" +msgstr "Find next" + +#: ../gui/src/ws_gui_layout.c:355 +msgid "ws_me_search_find_prev" +msgstr "Find previous" + +#: ../gui/src/ws_gui_layout.c:357 +msgid "ws_me_search_stop" +msgstr "Stop" + +#: ../gui/src/ws_gui_layout.c:560 +msgid "ws_mp_search" +msgstr "Search" + +#: ../gui/src/ws_gui_layout.c:580 +msgid "ws_mp_add_bookmark" +msgstr "Add Bookmark" + +#: ../gui/src/ws_gui_layout.c:580 +msgid "ws_mp_edit_copy" +msgstr "Copy" + +#: ../gui/src/ws_gui_layout.c:585 +msgid "ws_mp_edit_paste" +msgstr "Paste" + +#: ../gui/src/ws_gui_layout.c:590 +msgid "ws_mp_edit_select_all" +msgstr "Select All" + +#: ../gui/src/ws_gui_layout.c:597 +msgid "ws_mp_edit" +msgstr "Edit" + +#: ../gui/src/ws_gui_layout.c:605 +msgid "ws_mp_zoom_in" +msgstr "Zoom in" + +#: ../gui/src/ws_gui_layout.c:610 +msgid "ws_mp_zoom_out" +msgstr "Zoom out" + +#: ../gui/src/ws_gui_layout.c:712 ../gui/src/ws_gui_layout.c:904 +msgid "ws_ti_choose_dictionaries_title" +msgstr "Select dictionaries" + +#: ../gui/src/ws_gui_layout.c:767 ../gui/src/ws_gui_layout.c:941 +#: ../gui/src/ws_gui_layout.c:1233 ../gui/src/ws_gui_layout.c:1427 +#: ../gui/src/ws_gui_layout.c:1488 ../gui/src/ws_gui_layout.c:1432 +msgid "ws_db_cancel" +msgstr "Cancel" + +#: ../gui/src/ws_gui_layout.c:773 ../gui/src/ws_gui_layout.c:946 +#: ../gui/src/ws_gui_layout.c:1422 ../gui/src/ws_gui_layout.c:1483 +#: ../gui/src/ws_gui_layout.c:1427 +msgid "ws_db_ok" +msgstr "OK" + +#: ../gui/src/ws_gui_layout.c:892 +msgid "ws_ni_no_dictionaries_to_optimize" +msgstr "There are no dictionaries to optimize." + +#: ../gui/src/ws_gui_layout.c:1022 +msgid "ws_ti_load_dictionary_title" +msgstr "Load dictionary" + +#: ../gui/src/ws_gui_layout.c:1074 +msgid "ws_ni_dictionaries_activation_question" +msgstr "Would you like to start using this dictionary now?" + +#: ../gui/src/ws_gui_layout.c:1106 +msgid "ws_ni_dictionaries_optimalization_question" +msgstr "Would you like to optimize this dictionary?" + +#: ../gui/src/ws_gui_layout.c:1131 +msgid "ws_ni_dictionary_added" +msgstr "New dictionary has been added." + +#: ../gui/src/ws_gui_callbacks.c:439 +msgid "ws_ni_dictionary_not_added" +msgstr "Dictionary could not be added." + +#: ../gui/src/ws_gui_layout.c:1138 +msgid "ws_ni_dictionary_wrong_file" +msgstr "Wrong dictionary file." + +#: ../gui/src/ws_gui_layout.c:1189 +msgid "ws_ti_remove_dictionaries_title" +msgstr "Remove dictionaries" + +#: ../gui/src/ws_gui_layout.c:1239 +msgid "ws_bd_remove_dictionaries_remove_selected" +msgstr "Remove selected" + +#: ../gui/src/ws_gui_layout.c:1305 +msgid "ws_ti_about_title" +msgstr "About" + +#: ../gui/src/ws_gui_layout.c:1339 +msgid "ws_ib_dictionary_removed" +msgstr "Dictionary has been removed." + +#: ../gui/src/ws_gui_layout.c:1401 +msgid "ws_ti_add_bookmark" +msgstr "Add Bookmark" + +#: ../gui/src/ws_gui_layout.c:1413 +msgid "ws_ti_bookmarks_add_question" +msgstr "Add to Bookmarks?" + +#: ../gui/src/ws_gui_layout.c:1449 +msgid "ws_ni_bookmark_added" +msgstr "Bookmark has been added." + +#: ../gui/src/ws_gui_layout.c:1457 +msgid "ws_ni_bookmark_not_added" +msgstr "Bookmark could not be added." + +#: ../gui/src/ws_gui_layout.c:1462 +msgid "ws_ti_remove_bookmark" +msgstr "Remove Bookmark" + +#: ../gui/src/ws_gui_layout.c:1474 +msgid "ws_ni_remove_bookmark_question" +msgstr "Remove from Bookmarks?" + +#: ../gui/src/ws_gui_layout.c:1515 +msgid "ws_ni_bookmark_removed" +msgstr "Bookmark has been removed." + +#: ../gui/src/ws_gui_layout.c:1522 +msgid "ws_ni_bookmark_not_removed" +msgstr "Bookmark could not be removed." + +#: ../gui/src/ws_gui_callbacks.c:114 +msgid "ws_ni_error_occured" +msgstr "An error occured" + +#: ../gui/src/ws_gui_callbacks.c:133 +msgid "ws_ni_no_dictionary_available" +msgstr "There is no dictionary available." + +#: ../gui/src/ws_gui_callbacks.c:168 +msgid "ws_pb_caching" +msgstr "Caching..." + +#: ../gui/src/ws_gui_callbacks.c:168 +msgid "ws_pb_extracting" +msgstr "Extracting..." + +#: ../gui/src/ws_gui_callbacks.c:212 +msgid "ws_ni_dictionary_unavailable" +msgstr "Dictionary unavailable." + +#: ../gui/src/ws_gui_callbacks.c:289 +#: ../gui/src/ws_gui_layout.c:1534 +msgid "ws_ni_no_words_found" +msgstr "No words found." + +#: ../gui/src/ws_gui_callbacks.c:867 +msgid "ws_ni_no_text_selected" +msgstr "No text selected." + +#: ../gui/src/ws_gui_callbacks.c:970 +msgid "ws_ab_searching" +msgstr "Searching..." + +#: ../gui/src/ws_gui_callbacks.c:987 +msgid "ws_ni_no_word_typed" +msgstr "No word typed." + +#: ../gui/src/ws_gui_callbacks.c:1008 +msgid "ws_ni_search_aborted" +msgstr "Search has been aborted." + +#: ../gui/src/ws_gui_callbacks.c:1412 +msgid "ws_ni_select_word_to_add" +msgstr "Select word to add." + +#: ../gui/src/ws_gui_callbacks.c:1436 +msgid "ws_ni_select_word_to_remove" +msgstr "Select word to remove." + +#: ../gui/src/ws_gui_callbacks.c:1128 +msgid "ws_ib_max_zoom" +msgstr "Max zoom level reached." + +#: ../gui/src/ws_gui_callbacks.c:1152 +msgid "ws_ib_min_zoom" +msgstr "Min zoom level reached." + +#: ../gui/src/ws_gui_callbacks.c:1161 +msgid "ws_ib_zoom_in" +msgstr "Zoom in" + +#: ../gui/src/ws_gui_callbacks.c:1134 +msgid "ws_ib_zoom_out" +msgstr "Zoom out" + +#: ../gui/src/ws_gui_callbacks.c:1018 +msgid "ws_ib_fullscreen_on" +msgstr "Fullscreen" + +#: ../gui/src/ws_gui_callbacks.c:1029 +msgid "ws_ib_fullscreen_off" +msgstr "Fullscreen off" + +#: ../gui/src/ws_gui_callbacks.c:1124 +#: ../gui/src/ws_gui_callbacks.c:1157 +msgid "ws_ib_zoom_default" +msgstr "Default Zoom" + +#: ../gui/src/ws_gui_callbacks.c:1069 +msgid "ws_ib_copied" +msgstr "Copied." + +#: ../gui/src/ws_gui_callbacks.c:1096 +msgid "ws_ib_pasted" +msgstr "Pasted." + +#: ../gui/src/ws_gui_callbacks.c:268 +msgid "ws_ni_bookmarks_unavailable" +msgstr "Bookmarks could not be loaded. Please install libsqlite package." + +msgid "ws_ab_loading" +msgstr "Loading translation..." + +#: ../gui/src/ws_gui_layout.c:156 +msgid "ws_ti_list_full" +msgstr "Too many words" + +#: ../gui/src/ws_gui_layout.c:1780 +msgid "ws_ni_words_list_full" +msgstr "Query was too wide, WhiteStork is not able to show all words matching it. Please, precise more your query." diff --git a/data/locale/es.po b/data/locale/es.po new file mode 100644 index 0000000..7e5d8fc --- /dev/null +++ b/data/locale/es.po @@ -0,0 +1,354 @@ +# Copyright (C) 2006 +# This file is distributed under the same license as the PACKAGE package. +# Anna Gadomska , 2006. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-11-14 11:34+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Anna Gadomska \n" +"Language-Team: polish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../gui/src/ws_gui.c:49 +msgid "ws_check" +msgstr "OK" + +#: ../gui/src/ws_gui_layout.c:42 +msgid "ws_ni_welcome" +msgstr "Bienvenido a mDictionary" + +#: ../gui/src/ws_gui_layout.c:174 ../gui/src/ws_gui_layout.c:351 +msgid "ws_me_search_find" +msgstr "Encontrar" + +#: ../gui/src/ws_gui_layout.c:266 +msgid "ws_me_dictionaries" +msgstr "Diccionarios" + +#: ../gui/src/ws_gui_layout.c:268 +msgid "ws_me_bookmarks" +msgstr "Marcadores" + +#: ../gui/src/ws_gui_layout.c:270 +msgid "ws_me_edit" +msgstr "Editar" + +#: ../gui/src/ws_gui_layout.c:272 +msgid "ws_me_view" +msgstr "Ver" + +#: ../gui/src/ws_gui_layout.c:274 +msgid "ws_me_search" +msgstr "Buscar" + +#: ../gui/src/ws_gui_layout.c:276 +msgid "ws_me_about" +msgstr "Acerca de..." + +#: ../gui/src/ws_gui_layout.c:278 +msgid "ws_me_close" +msgstr "Cerrar" + +#: ../gui/src/ws_gui_layout.c:285 +msgid "ws_me_dictionaries_load" +msgstr "Cargar diccionario..." + +#: ../gui/src/ws_gui_layout.c:287 +msgid "ws_me_dictionaries_select" +msgstr "Seleccionar diccionarios..." + +#: ../gui/src/ws_gui_layout.c:289 +msgid "ws_me_dictionaries_remove" +msgstr "Eliminar diccionarios..." + +#: ../gui/src/ws_gui_layout.c:291 +msgid "ws_me_dictionaries_optimize" +msgstr "Optimizar diccionarios..." + +#: ../gui/src/ws_gui_layout.c:303 +msgid "ws_me_bookmarks_open" +msgstr "Abrir marcadores" + +#: ../gui/src/ws_gui_layout.c:305 +msgid "ws_me_bookmarks_close" +msgstr "Cerrar marcadores" + +#: ../gui/src/ws_gui_layout.c:307 +msgid "ws_me_bookmarks_add" +msgstr "Añadir marcado..." + +#: ../gui/src/ws_gui_layout.c:309 +msgid "ws_me_bookmarks_remove" +msgstr "Eliminar marcador..." + +#: ../gui/src/ws_gui_layout.c:321 +msgid "ws_me_edit_copy" +msgstr "Copiar" + +#: ../gui/src/ws_gui_layout.c:323 +msgid "ws_me_edit_paste" +msgstr "Pegar" + +#: ../gui/src/ws_gui_layout.c:325 +msgid "ws_me_edit_select_all" +msgstr "Seleccionar todo" + +#: ../gui/src/ws_gui_layout.c:334 +msgid "ws_me_view_hide_words_list" +msgstr "Ocultar la lista de palabras" + +#: ../gui/src/ws_gui_layout.c:336 +msgid "ws_me_view_zoom_in" +msgstr "Aumentar" + +#: ../gui/src/ws_gui_layout.c:338 +msgid "ws_me_view_zoom_out" +msgstr "Disminuir" + +#: ../gui/src/ws_gui_layout.c:340 +msgid "ws_me_view_fullscreen" +msgstr "Pantalla completa" + +#: ../gui/src/ws_gui_layout.c:353 +msgid "ws_me_search_find_next" +msgstr "Buscar siguiente" + +#: ../gui/src/ws_gui_layout.c:355 +msgid "ws_me_search_find_prev" +msgstr "Buscar anterior" + +#: ../gui/src/ws_gui_layout.c:357 +msgid "ws_me_search_stop" +msgstr "Detener" + +#: ../gui/src/ws_gui_layout.c:560 +msgid "ws_mp_search" +msgstr "Buscar" + +#: ../gui/src/ws_gui_layout.c:580 +msgid "ws_mp_add_bookmark" +msgstr "Añadir marcado" + +#: ../gui/src/ws_gui_layout.c:580 +msgid "ws_mp_edit_copy" +msgstr "Copiar" + +#: ../gui/src/ws_gui_layout.c:585 +msgid "ws_mp_edit_paste" +msgstr "Pegar" + +#: ../gui/src/ws_gui_layout.c:590 +msgid "ws_mp_edit_select_all" +msgstr "Seleccionar todo" + +#: ../gui/src/ws_gui_layout.c:597 +msgid "ws_mp_edit" +msgstr "Editar" + +#: ../gui/src/ws_gui_layout.c:605 +msgid "ws_mp_zoom_in" +msgstr "Aumentar" + +#: ../gui/src/ws_gui_layout.c:610 +msgid "ws_mp_zoom_out" +msgstr "Disminuir" + +#: ../gui/src/ws_gui_layout.c:712 ../gui/src/ws_gui_layout.c:904 +msgid "ws_ti_choose_dictionaries_title" +msgstr "Elegir diccionarios" + +#: ../gui/src/ws_gui_layout.c:767 ../gui/src/ws_gui_layout.c:941 +#: ../gui/src/ws_gui_layout.c:1233 ../gui/src/ws_gui_layout.c:1427 +#: ../gui/src/ws_gui_layout.c:1488 ../gui/src/ws_gui_layout.c:1432 +msgid "ws_db_cancel" +msgstr "Cancelar" + +#: ../gui/src/ws_gui_layout.c:773 ../gui/src/ws_gui_layout.c:946 +#: ../gui/src/ws_gui_layout.c:1422 ../gui/src/ws_gui_layout.c:1483 +#: ../gui/src/ws_gui_layout.c:1427 +msgid "ws_db_ok" +msgstr "OK" + +#: ../gui/src/ws_gui_layout.c:892 +msgid "ws_ni_no_dictionaries_to_optimize" +msgstr "No hay ningún diccionario para optimizar." + +#: ../gui/src/ws_gui_layout.c:1022 +msgid "ws_ti_load_dictionary_title" +msgstr "Cargar diccionario" + +#: ../gui/src/ws_gui_layout.c:1074 +msgid "ws_ni_dictionaries_activation_question" +msgstr "¿Quiere comenzar a usar este diccionario?" + +#: ../gui/src/ws_gui_layout.c:1106 +msgid "ws_ni_dictionaries_optimalization_question" +msgstr "¿Quiere optimizar este diccionario?" + +#: ../gui/src/ws_gui_layout.c:1131 +#: ../gui/src/ws_gui_callbacks.c:447 +msgid "ws_ni_dictionary_added" +msgstr "Se ha añadido un diccionario nuevo." + +#: ../gui/src/ws_gui_callbacks.c:439 +msgid "ws_ni_dictionary_not_added" +msgstr "No se ha añadido un diccionario nuevo." + +#: ../gui/src/ws_gui_layout.c:1138 +msgid "ws_ni_dictionary_wrong_file" +msgstr "Archivo de diccionario incorrecto." + +#: ../gui/src/ws_gui_layout.c:1189 +msgid "ws_ti_remove_dictionaries_title" +msgstr "Eliminar diccionarios" + +#: ../gui/src/ws_gui_layout.c:1239 +msgid "ws_bd_remove_dictionaries_remove_selected" +msgstr "Eliminar la selección" + +#: ../gui/src/ws_gui_layout.c:1305 +msgid "ws_ti_about_title" +msgstr "Acerca de" + +#: ../gui/src/ws_gui_layout.c:1339 +msgid "ws_ib_dictionary_removed" +msgstr "El diccionario se ha eliminado." + +#: ../gui/src/ws_gui_layout.c:1401 +msgid "ws_ti_add_bookmark" +msgstr "Añadir marcadr" + +#: ../gui/src/ws_gui_layout.c:1413 +msgid "ws_ti_bookmarks_add_question" +msgstr "¿Añadir a los marcadores?" + +#: ../gui/src/ws_gui_layout.c:1449 +msgid "ws_ni_bookmark_added" +msgstr "Se ha añadido el marcador." + +#: ../gui/src/ws_gui_layout.c:1457 +msgid "ws_ni_bookmark_not_added" +msgstr "No se ha podido añadir el marcado." + +#: ../gui/src/ws_gui_layout.c:1462 +msgid "ws_ti_remove_bookmark" +msgstr "Eliminar marcador" + +#: ../gui/src/ws_gui_layout.c:1474 +msgid "ws_ni_remove_bookmark_question" +msgstr "¿Eliminar de los marcadores?" + +#: ../gui/src/ws_gui_layout.c:1515 +msgid "ws_ni_bookmark_removed" +msgstr "Se ha eliminado el marcador." + +#: ../gui/src/ws_gui_layout.c:1522 +msgid "ws_ni_bookmark_not_removed" +msgstr "No se ha podido eliminar el marcador." + +#: ../gui/src/ws_gui_callbacks.c:114 +msgid "ws_ni_error_occured" +msgstr "Ocurrió un error" + +#: ../gui/src/ws_gui_callbacks.c:133 +msgid "ws_ni_no_dictionary_available" +msgstr "No hay ningún diccionario disponibl." + +#: ../gui/src/ws_gui_callbacks.c:168 +msgid "ws_pb_caching" +msgstr "Almacenando..." + +#: ../gui/src/ws_gui_callbacks.c:168 +msgid "ws_pb_extracting" +msgstr "Extracting..." + +#: ../gui/src/ws_gui_callbacks.c:212 +msgid "ws_ni_dictionary_unavailable" +msgstr "Diccionario no disponible." + +#: ../gui/src/ws_gui_callbacks.c:289 +#: ../gui/src/ws_gui_layout.c:1534 +msgid "ws_ni_no_words_found" +msgstr "No se ha encontrado ninguna palabra." + +#: ../gui/src/ws_gui_callbacks.c:867 +msgid "ws_ni_no_text_selected" +msgstr "No se ha seleccionado ningún text." + +#: ../gui/src/ws_gui_callbacks.c:970 +msgid "ws_ab_searching" +msgstr "Buscando..." + +#: ../gui/src/ws_gui_callbacks.c:987 +msgid "ws_ni_no_word_typed" +msgstr "No se ha escrito ninguna palabra." + +#: ../gui/src/ws_gui_callbacks.c:1008 +msgid "ws_ni_search_aborted" +msgstr "La búsqueda ha sido cancelada." + +#: ../gui/src/ws_gui_callbacks.c:1412 +msgid "ws_ni_select_word_to_add" +msgstr "Seleccione la palabra a añadir." + +#: ../gui/src/ws_gui_callbacks.c:1436 +msgid "ws_ni_select_word_to_remove" +msgstr "Seleccione la palabra a eliminar." + +#: ../gui/src/ws_gui_callbacks.c:1128 +msgid "ws_ib_max_zoom" +msgstr "Máximo nivel de zoo." + +#: ../gui/src/ws_gui_callbacks.c:1152 +msgid "ws_ib_min_zoom" +msgstr "Mínimo nivel de zoo." + +#: ../gui/src/ws_gui_callbacks.c:1161 +msgid "ws_ib_zoom_in" +msgstr "Aumentar" + +#: ../gui/src/ws_gui_callbacks.c:1134 +msgid "ws_ib_zoom_out" +msgstr "Disminuir" + +#: ../gui/src/ws_gui_callbacks.c:1018 +msgid "ws_ib_fullscreen_on" +msgstr "Pantalla completa" + +#: ../gui/src/ws_gui_callbacks.c:1029 +msgid "ws_ib_fullscreen_off" +msgstr "Salir de pantalla completa" + +#: ../gui/src/ws_gui_callbacks.c:1124 +#: ../gui/src/ws_gui_callbacks.c:1157 +msgid "ws_ib_zoom_default" +msgstr "Nivel de zoom por defecto" + +#: ../gui/src/ws_gui_callbacks.c:1069 +msgid "ws_ib_copied" +msgstr "Copiado." + +#: ../gui/src/ws_gui_callbacks.c:1096 +msgid "ws_ib_pasted" +msgstr "Pegado." + +#: ../gui/src/ws_gui_callbacks.c:268 +msgid "ws_ni_bookmarks_unavailable" +msgstr "No se han podido cargar los marcadores. Instale el paquete libsqlite." + +msgid "ws_ab_loading" +msgstr "ws_ab_loading" + +#: ../gui/src/ws_gui_layout.c:156 +msgid "ws_ti_list_full" +msgstr "ws_ti_list_full" + +#: ../gui/src/ws_gui_layout.c:1780 +msgid "ws_ni_words_list_full" +msgstr "ws_ni_words_list_full" diff --git a/data/locale/pl_PL.po b/data/locale/pl_PL.po new file mode 100644 index 0000000..b06d0e3 --- /dev/null +++ b/data/locale/pl_PL.po @@ -0,0 +1,348 @@ +# Copyright (C) 2006 +# This file is distributed under the same license as the PACKAGE package. +# Anna Gadomska, , 2006. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-11-14 11:34+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Anna Gadomska \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../gui/src/ws_gui.c:49 +msgid "ws_check" +msgstr "OK" + +#: ../gui/src/ws_gui_layout.c:42 +msgid "ws_ni_welcome" +msgstr "Witamy w mDictionary!" + +#: ../gui/src/ws_gui_layout.c:174 ../gui/src/ws_gui_layout.c:351 +msgid "ws_me_search_find" +msgstr "Znajdź" + +#: ../gui/src/ws_gui_layout.c:266 +msgid "ws_me_dictionaries" +msgstr "Słowniki" + +#: ../gui/src/ws_gui_layout.c:268 +msgid "ws_me_bookmarks" +msgstr "Zakładki" + +#: ../gui/src/ws_gui_layout.c:270 +msgid "ws_me_edit" +msgstr "Edycja" + +#: ../gui/src/ws_gui_layout.c:272 +msgid "ws_me_view" +msgstr "Widok" + +#: ../gui/src/ws_gui_layout.c:274 +msgid "ws_me_search" +msgstr "Znajdź" + +#: ../gui/src/ws_gui_layout.c:276 +msgid "ws_me_about" +msgstr "O programie..." + +#: ../gui/src/ws_gui_layout.c:278 +msgid "ws_me_close" +msgstr "Zamknij" + +#: ../gui/src/ws_gui_layout.c:285 +msgid "ws_me_dictionaries_load" +msgstr "Załaduj słownik..." + +#: ../gui/src/ws_gui_layout.c:287 +msgid "ws_me_dictionaries_select" +msgstr "Wybierz słowniki..." + +#: ../gui/src/ws_gui_layout.c:289 +msgid "ws_me_dictionaries_remove" +msgstr "Usuń słowniki..." + +#: ../gui/src/ws_gui_layout.c:291 +msgid "ws_me_dictionaries_optimize" +msgstr "Optymalizuj słowniki..." + +#: ../gui/src/ws_gui_layout.c:303 +msgid "ws_me_bookmarks_open" +msgstr "Otwórz Zakładki" + +#: ../gui/src/ws_gui_layout.c:305 +msgid "ws_me_bookmarks_close" +msgstr "Zamknij Zakładki" + +#: ../gui/src/ws_gui_layout.c:307 +msgid "ws_me_bookmarks_add" +msgstr "Dodaj do Zakłade..." + +#: ../gui/src/ws_gui_layout.c:309 +msgid "ws_me_bookmarks_remove" +msgstr "Usuń z Zakład..." + +#: ../gui/src/ws_gui_layout.c:321 +msgid "ws_me_edit_copy" +msgstr "Kopiuj" + +#: ../gui/src/ws_gui_layout.c:323 +msgid "ws_me_edit_paste" +msgstr "Wklej" + +#: ../gui/src/ws_gui_layout.c:325 +msgid "ws_me_edit_select_all" +msgstr "Zaznacz wszystko" + +#: ../gui/src/ws_gui_layout.c:334 +msgid "ws_me_view_hide_words_list" +msgstr "Ukryj listę słów" + +#: ../gui/src/ws_gui_layout.c:336 +msgid "ws_me_view_zoom_in" +msgstr "Powiększ" + +#: ../gui/src/ws_gui_layout.c:338 +msgid "ws_me_view_zoom_out" +msgstr "Pomniejsz" + +#: ../gui/src/ws_gui_layout.c:340 +msgid "ws_me_view_fullscreen" +msgstr "Pełny ekran" + +#: ../gui/src/ws_gui_layout.c:353 +msgid "ws_me_search_find_next" +msgstr "Znajdź następny" + +#: ../gui/src/ws_gui_layout.c:355 +msgid "ws_me_search_find_prev" +msgstr "Znajdź poprzedni" + +#: ../gui/src/ws_gui_layout.c:357 +msgid "ws_me_search_stop" +msgstr "Zatrzymaj" + +#: ../gui/src/ws_gui_layout.c:560 +msgid "ws_mp_search" +msgstr "Znajdź" + +#: ../gui/src/ws_gui_layout.c:580 +msgid "ws_mp_edit_copy" +msgstr "Kopiuj" + +#: ../gui/src/ws_gui_layout.c:585 +msgid "ws_mp_edit_paste" +msgstr "Wklej" + +#: ../gui/src/ws_gui_layout.c:590 +msgid "ws_mp_edit_select_all" +msgstr "Zaznacz wszystko" + +#: ../gui/src/ws_gui_layout.c:597 +msgid "ws_mp_edit" +msgstr "Edycja" + +#: ../gui/src/ws_gui_layout.c:605 +msgid "ws_mp_zoom_in" +msgstr "Powiększ" + +#: ../gui/src/ws_gui_layout.c:610 +msgid "ws_mp_zoom_out" +msgstr "Pomniejsz" + +#: ../gui/src/ws_gui_layout.c:712 ../gui/src/ws_gui_layout.c:904 +msgid "ws_ti_choose_dictionaries_title" +msgstr "Wybierz słowniki" + +#: ../gui/src/ws_gui_layout.c:767 ../gui/src/ws_gui_layout.c:941 +#: ../gui/src/ws_gui_layout.c:1233 ../gui/src/ws_gui_layout.c:1427 +#: ../gui/src/ws_gui_layout.c:1488 +msgid "ws_db_cancel" +msgstr "Anuluj" + +#: ../gui/src/ws_gui_layout.c:773 ../gui/src/ws_gui_layout.c:946 +#: ../gui/src/ws_gui_layout.c:1422 ../gui/src/ws_gui_layout.c:1483 +msgid "ws_db_ok" +msgstr "OK" + +#: ../gui/src/ws_gui_layout.c:892 +msgid "ws_ni_no_dictionaries_to_optimize" +msgstr "Brak słowników do zoptymalizowania." + +#: ../gui/src/ws_gui_layout.c:1022 +msgid "ws_ti_load_dictionary_title" +msgstr "Załaduj słownik" + +#: ../gui/src/ws_gui_layout.c:1074 +msgid "ws_ni_dictionaries_activation_question" +msgstr "Czy chcesz zacząć używać ten słownik już teraz?" + +#: ../gui/src/ws_gui_layout.c:1106 +msgid "ws_ni_dictionaries_optimalization_question" +msgstr "Czy chcesz zoptymalizowac ten słownik teraz?" + +#: ../gui/src/ws_gui_layout.c:1131 +msgid "ws_ni_dictionary_added" +msgstr "Nowy słownik został dodany." + +#: ../gui/src/ws_gui_callbacks.c:439 +msgid "ws_ni_dictionary_not_added" +msgstr "Słownik nie mógł zostać dodany." + +#: ../gui/src/ws_gui_layout.c:1138 +msgid "ws_ni_dictionary_wrong_file" +msgstr "Zły plik słownika." + +#: ../gui/src/ws_gui_layout.c:1189 +msgid "ws_ti_remove_dictionaries_title" +msgstr "Usuń słowniki" + +#: ../gui/src/ws_gui_layout.c:1239 +msgid "ws_bd_remove_dictionaries_remove_selected" +msgstr "Usuń zaznaczone" + +#: ../gui/src/ws_gui_layout.c:1305 +msgid "ws_ti_about_title" +msgstr "O Programie" + +#: ../gui/src/ws_gui_layout.c:1401 +msgid "ws_ti_add_bookmark" +msgstr "Dodaj do zakładk" + +#: ../gui/src/ws_gui_layout.c:1413 +msgid "ws_ti_bookmarks_add_question" +msgstr "Dodać do zakładek?" + +#: ../gui/src/ws_gui_layout.c:1449 +msgid "ws_ni_bookmark_added" +msgstr "Zakładka została dana." + +#: ../gui/src/ws_gui_layout.c:1457 +msgid "ws_ni_bookmark_not_added" +msgstr "Zakładka nie mogła być dod." + + +#: ../gui/src/ws_gui_layout.c:1462 +msgid "ws_ti_remove_bookmark" +msgstr "Usuń zakładk" + +#: ../gui/src/ws_gui_layout.c:1474 +msgid "ws_ni_remove_bookmark_question" +msgstr "Usunąć z zakładek?" + +#: ../gui/src/ws_gui_layout.c:1515 +msgid "ws_ni_bookmark_removed" +msgstr "Zakładkę usunieto." + +#: ../gui/src/ws_gui_layout.c:1522 +msgid "ws_ni_bookmark_not_removed" +msgstr "Zakładka nie mogła zostać usunięta." + +#: ../gui/src/ws_gui_callbacks.c:114 +msgid "ws_ni_error_occured" +msgstr "Wystąpił błąd." + +#: ../gui/src/ws_gui_callbacks.c:119 +msgid "response" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:133 +msgid "ws_ni_no_dictionary_available" +msgstr "Brak dostępnych słowników." + +#: ../gui/src/ws_gui_callbacks.c:168 +msgid "ws_pb_caching" +msgstr "Trwa optymalizacja..." + +#: ../gui/src/ws_gui_callbacks.c:168 +msgid "ws_pb_extracting" +msgstr "Trwa rozpakowywanie..." + +#: ../gui/src/ws_gui_callbacks.c:212 +msgid "ws_ni_dictionary_unavailable" +msgstr "Słownik niedostępny." + +#: ../gui/src/ws_gui_callbacks.c:289 +msgid "ws_ni_no_words_found" +msgstr "Nie znaleziono słów." + +#: ../gui/src/ws_gui_callbacks.c:867 +msgid "ws_ni_no_text_selected" +msgstr "Zaznacz tekst." + +#: ../gui/src/ws_gui_callbacks.c:970 +msgid "ws_ab_searching" +msgstr "Wyszukiwanie..." + +#: ../gui/src/ws_gui_callbacks.c:987 +msgid "ws_ni_no_word_typed" +msgstr "Nie wpisano słowa." + +#: ../gui/src/ws_gui_callbacks.c:1008 +msgid "ws_ni_search_aborted" +msgstr "Wyszukiwanie zostało przerwane." + +#: ../gui/src/ws_gui_callbacks.c:1412 +msgid "ws_ni_select_word_to_add" +msgstr "Wybierz słowo do dodania." + +#: ../gui/src/ws_gui_callbacks.c:1436 +msgid "ws_ni_select_word_to_remove" +msgstr "Wybierz słowo do usunięcia." + +#: ../gui/src/ws_gui_callbacks.c:1128 +msgid "ws_ib_max_zoom" +msgstr "Nie można bardziej powiększy." + +#: ../gui/src/ws_gui_callbacks.c:1152 +msgid "ws_ib_min_zoom" +msgstr "Nie można bardziej pomniejszyć." + +#: ../gui/src/ws_gui_callbacks.c:1161 +msgid "ws_ib_zoom_in" +msgstr "Powiększenie" + +#: ../gui/src/ws_gui_callbacks.c:1134 +msgid "ws_ib_zoom_out" +msgstr "Pomniejszenie" + +#: ../gui/src/ws_gui_callbacks.c:1018 +msgid "ws_ib_fullscreen_on" +msgstr "Pełen ekran włączony" + +#: ../gui/src/ws_gui_callbacks.c:1029 +msgid "ws_ib_fullscreen_off" +msgstr "Pełen ekran wyłączony" + +#: ../gui/src/ws_gui_callbacks.c:1124 +#: ../gui/src/ws_gui_callbacks.c:1157 +msgid "ws_ib_zoom_default" +msgstr "Domyślna wartość powiększenia" + +#: ../gui/src/ws_gui_callbacks.c:1069 +msgid "ws_ib_copied" +msgstr "Skopiowano." + +#: ../gui/src/ws_gui_callbacks.c:1096 +msgid "ws_ib_pasted" +msgstr "Wklejono." + +#: ../gui/src/ws_gui_callbacks.c:268 +msgid "ws_ni_bookmarks_unavailable" +msgstr "Moduł Zakładek nie mógl być załadowany. Proszę doinstalować paczkę libsqlite." + +msgid "ws_ab_loading" +msgstr "Wczytywanie tłumaczenia..." + +#: ../gui/src/ws_gui_layout.c:156 +msgid "ws_ti_list_full" +msgstr "Za dużo wynikow" + +#: ../gui/src/ws_gui_layout.c:1780 +msgid "ws_ni_words_list_full" +msgstr "Jeśli nie znalazłeś szukanego słowa sprecyzuj zapytanie." diff --git a/data/mis/whitestork-search.xml b/data/mis/whitestork-search.xml new file mode 100644 index 0000000..63abce4 --- /dev/null +++ b/data/mis/whitestork-search.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/data/other/org.maemo.WhiteStorkGui.service b/data/other/org.maemo.WhiteStorkGui.service new file mode 100644 index 0000000..6eaf142 --- /dev/null +++ b/data/other/org.maemo.WhiteStorkGui.service @@ -0,0 +1,4 @@ +# Sample service description file +[D-BUS Service] +Name=org.maemo.WhiteStorkGui +Exec=/usr/bin/WhiteStork diff --git a/data/other/org.maemo.WhiteStorkManager.service b/data/other/org.maemo.WhiteStorkManager.service new file mode 100644 index 0000000..92c3155 --- /dev/null +++ b/data/other/org.maemo.WhiteStorkManager.service @@ -0,0 +1,4 @@ +# Sample service description file +[D-BUS Service] +Name=org.maemo.WhiteStorkManager +Exec=/usr/bin/WhiteStorkManager diff --git a/data/other/whitestork.desktop b/data/other/whitestork.desktop new file mode 100644 index 0000000..8870c02 --- /dev/null +++ b/data/other/whitestork.desktop @@ -0,0 +1,20 @@ +[Desktop Entry] +Encoding=UTF-8 +Version=1.0 +Name=WhiteStork Dictionary +Comment=Multilingual dictionary +Exec=/usr/bin/WhiteStork +X-Osso-Service=org.maemo.WhiteStorkGui +Icon=whitestork_icon +Terminal=true +Type=Application +X-HildonDesk-ShowInToolbar=true +X-Osso-Type=application/x-executable +X-Window-Icon=whitestork_icon + +X-Osso-URI-Actions=mdict; + +[X-Osso-URI-Action Handler mdict] +Method=search_home_applet +Name=uri_link_open_link +TranslationDomain=osso-uri \ No newline at end of file diff --git a/data/package_contents/whitestork/DEBIAN/control b/data/package_contents/whitestork/DEBIAN/control new file mode 100644 index 0000000..02e7fda --- /dev/null +++ b/data/package_contents/whitestork/DEBIAN/control @@ -0,0 +1,31 @@ +Package: whitestork +Version: +Section: user/office +Priority: optional +Architecture: all +Installed-Size: +Depends: libexpat1 (>= 1.95.8) +Maintainer: ComArch S.A. +Description: Multilingual dictionary. + WhiteStork Multilingual Dictionary is a very functional + application allowing the use of many dictionary engines. + You can either download them from our homepage at + http://garage.maemo.org, or write your own, provided + that You stick to the API (also available on our homepage). + The graphical user interface of our application can also + be replaced by a product of Your own programming skills. + Copyright 2006, ComArch S.A. +Maemo-Icon-26: + iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI + WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1wEJDBUeRyfCHgAAAk5JREFUSMftlk9LVGEUxn937lzv + nROjZDOpYdg/E3XQoiCEsk1R0CosXPUJ2rVp0baP0Aco2rRxE0FhRFGRmzbRH9IW0SJBLFKpR67j + eFv4DkyTOtMoLaKzet/3POc8nHuf+7wX/rXwGqyLgHNuHUdRNJFKpeYlLa9X4NfZuAXYAWSjKOpK + kmQoSZK7wAhwC7ji+35zEASFIAi+FItFrTXRNiAPcAT25+AQwGHo7YQ+gD2wtxXaJ0GXff+8SqUs + MA58BHLAJUAAYRimfN9/Imm2kig9BFd7YdQ1TI/CvnIyB7RWgK+H4TXF8bibZAWYcSkBYwBxHI+Y + 2XB5v947SgO95c0p6M9DD0AHtN3JZCamFxdvA4XVIwQ0A+/ddC1Aj5ntljTWsHLMrNvMBty2GTgI + WBXmuJm1bVp1ZtYNDLhp5ipSeSAAnkua2Sp5Y2ZZ4IIj+wBMSiquh083QNAGDALHHEE38G4jkron + MrPTQNbhZ4BXVZAunGiAJeCRJNVNZGYF1+ChpJPAV+BFjZpgVbD8kPS0JpEjKUqarDjuAC669Sfg + fsUUv0Qmk9npeV6/pMe1iEZqfAtp4Kzr0bRGfiUMw3bf929KWkxvwpCXgXsbAXzfP1P209QGuFkz + y29C/k1AIOl7PWIYBmLgpaTSH5D0ONk/KF8dXh1FncBR9wjeAguSpqsw24F8LkkKyxDOed5rSW8a + dgYz63PGuasq9e3G0tLgiVLp2YEkWfBgasssqDqS1atjCojXIkr9rX+G/0QNR3oLe30G5p1j/BY/ + AaknsXLnUsw8AAAAAElFTkSuQmCC diff --git a/data/package_contents/whitestork/DEBIAN/postinst b/data/package_contents/whitestork/DEBIAN/postinst new file mode 100755 index 0000000..b65f299 --- /dev/null +++ b/data/package_contents/whitestork/DEBIAN/postinst @@ -0,0 +1,23 @@ +#!/bin/sh + +echo -e "Postinstalling actions..." + +if [ "$1" != "upgrade" ] +then +# End automatically added section +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/elements/name "Elements Database"' +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/elements/path "/usr/share/WhiteStork/dictionaries/elements"' +su $USER -c 'gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/elements/active true' +su $USER -c 'gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/elements/optimized true' +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/us-en/name "American - English Dictionary"' +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/us-en/path "/usr/share/WhiteStork/dictionaries/us-en"' +su $USER -c 'gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/us-en/active true' +su $USER -c 'gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/us-en/optimized false' + +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Engines/bookmarks/path "/usr/lib/WhiteStork/ws_bookmark.so"' +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/bookmarks/name "Bookmarks"' +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/bookmarks/path "/usr/share/WhiteStork/dictionaries/bookmarks"' +su $USER -c 'gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/bookmarks/active false' +su $USER -c 'gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/bookmarks/optimized true' +chmod -R 0777 /usr/share/WhiteStork/dictionaries +fi \ No newline at end of file diff --git a/data/package_contents/whitestork/DEBIAN/postrm b/data/package_contents/whitestork/DEBIAN/postrm new file mode 100755 index 0000000..36c6660 --- /dev/null +++ b/data/package_contents/whitestork/DEBIAN/postrm @@ -0,0 +1,3 @@ +#!/bin/sh + +echo -e "Postremoving actions..." diff --git a/data/package_contents/whitestork/DEBIAN/preinst b/data/package_contents/whitestork/DEBIAN/preinst new file mode 100755 index 0000000..302910b --- /dev/null +++ b/data/package_contents/whitestork/DEBIAN/preinst @@ -0,0 +1,3 @@ +#!/bin/sh + +echo -e "Preinstallation actions..." diff --git a/data/package_contents/whitestork/DEBIAN/prerm b/data/package_contents/whitestork/DEBIAN/prerm new file mode 100755 index 0000000..ef59312 --- /dev/null +++ b/data/package_contents/whitestork/DEBIAN/prerm @@ -0,0 +1,14 @@ +#!/bin/sh + +echo -e "Preremoving actions..." + +#su $USER -c 'rm -rf /usr/share/WhiteStork' + +if [ "$1" != "upgrade" ] +then + echo -e -n "Removing gconf configuration..\n" + su $USER -c 'gconftool-2 --recursive-unset /apps/maemo/WhiteStork/Dictionaries' + su $USER -c 'gconftool-2 --recursive-unset /apps/maemo/WhiteStork/Engines/bookmarks' +fi + +# End automatically added section diff --git a/data/package_contents/whitestorkdictionary/DEBIAN/control b/data/package_contents/whitestorkdictionary/DEBIAN/control new file mode 100644 index 0000000..fd6060a --- /dev/null +++ b/data/package_contents/whitestorkdictionary/DEBIAN/control @@ -0,0 +1,12 @@ +Package: whitestorkdictionary +Version: +Section: user/office +Priority: optional +Architecture: all +Installed-Size: +Depends: whitestorkgui (>= 0.1.0), whitestork (>= 0.1.0), whitestorkplugins (>= 0.1.0) +Maintainer: ComArch S.A. +Description: metapackage binding all WhiteStork Dictionary's components + This package gathers all WhiteStork's components together, increasing + the ease of use of WhiteStork Multilingual Dictionary. + Copyright 2006, ComArch S.A. diff --git a/data/package_contents/whitestorkdictionary/DEBIAN/postinst b/data/package_contents/whitestorkdictionary/DEBIAN/postinst new file mode 100755 index 0000000..d7b09f0 --- /dev/null +++ b/data/package_contents/whitestorkdictionary/DEBIAN/postinst @@ -0,0 +1,3 @@ +#!/bin/sh + +echo -e "Postinstalling actions..." diff --git a/data/package_contents/whitestorkdictionary/DEBIAN/postrm b/data/package_contents/whitestorkdictionary/DEBIAN/postrm new file mode 100755 index 0000000..36c6660 --- /dev/null +++ b/data/package_contents/whitestorkdictionary/DEBIAN/postrm @@ -0,0 +1,3 @@ +#!/bin/sh + +echo -e "Postremoving actions..." diff --git a/data/package_contents/whitestorkdictionary/DEBIAN/preinst b/data/package_contents/whitestorkdictionary/DEBIAN/preinst new file mode 100755 index 0000000..302910b --- /dev/null +++ b/data/package_contents/whitestorkdictionary/DEBIAN/preinst @@ -0,0 +1,3 @@ +#!/bin/sh + +echo -e "Preinstallation actions..." diff --git a/data/package_contents/whitestorkdictionary/DEBIAN/prerm b/data/package_contents/whitestorkdictionary/DEBIAN/prerm new file mode 100755 index 0000000..9bd24b7 --- /dev/null +++ b/data/package_contents/whitestorkdictionary/DEBIAN/prerm @@ -0,0 +1,3 @@ +#!/bin/sh + +echo -e "Preremoving actions..." diff --git a/data/package_contents/whitestorkgui/DEBIAN/control b/data/package_contents/whitestorkgui/DEBIAN/control new file mode 100644 index 0000000..4e0ce7d --- /dev/null +++ b/data/package_contents/whitestorkgui/DEBIAN/control @@ -0,0 +1,27 @@ +Package: whitestorkgui +Version: +Section: user/office +Priority: optional +Architecture: all +Installed-Size: +Depends: libexpat1 (>= 1.95.8), whitestork (>= 0.1.0) +Maintainer: ComArch S.A. +Description: GUI for whitestork. + This package contain an example of GUI for + Whitestork - Multilingual Dictionary for + Maemo platform. + Copyright 2006, ComArch S.A. +Maemo-Icon-26: + iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI + WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1wEJDBUeRyfCHgAAAk5JREFUSMftlk9LVGEUxn937lzv + nROjZDOpYdg/E3XQoiCEsk1R0CosXPUJ2rVp0baP0Aco2rRxE0FhRFGRmzbRH9IW0SJBLFKpR67j + eFv4DkyTOtMoLaKzet/3POc8nHuf+7wX/rXwGqyLgHNuHUdRNJFKpeYlLa9X4NfZuAXYAWSjKOpK + kmQoSZK7wAhwC7ji+35zEASFIAi+FItFrTXRNiAPcAT25+AQwGHo7YQ+gD2wtxXaJ0GXff+8SqUs + MA58BHLAJUAAYRimfN9/Imm2kig9BFd7YdQ1TI/CvnIyB7RWgK+H4TXF8bibZAWYcSkBYwBxHI+Y + 2XB5v947SgO95c0p6M9DD0AHtN3JZCamFxdvA4XVIwQ0A+/ddC1Aj5ntljTWsHLMrNvMBty2GTgI + WBXmuJm1bVp1ZtYNDLhp5ipSeSAAnkua2Sp5Y2ZZ4IIj+wBMSiquh083QNAGDALHHEE38G4jkron + MrPTQNbhZ4BXVZAunGiAJeCRJNVNZGYF1+ChpJPAV+BFjZpgVbD8kPS0JpEjKUqarDjuAC669Sfg + fsUUv0Qmk9npeV6/pMe1iEZqfAtp4Kzr0bRGfiUMw3bf929KWkxvwpCXgXsbAXzfP1P209QGuFkz + y29C/k1AIOl7PWIYBmLgpaTSH5D0ONk/KF8dXh1FncBR9wjeAguSpqsw24F8LkkKyxDOed5rSW8a + dgYz63PGuasq9e3G0tLgiVLp2YEkWfBgasssqDqS1atjCojXIkr9rX+G/0QNR3oLe30G5p1j/BY/ + AaknsXLnUsw8AAAAAElFTkSuQmCC diff --git a/data/package_contents/whitestorkgui/DEBIAN/postinst b/data/package_contents/whitestorkgui/DEBIAN/postinst new file mode 100755 index 0000000..3ad6118 --- /dev/null +++ b/data/package_contents/whitestorkgui/DEBIAN/postinst @@ -0,0 +1,17 @@ +#!/bin/sh + +#echo $1 >> /home/krzsas/log.txt +echo -e "Postinstalling actions..." +su $USER -c 'ln -s /usr/share/applications/hildon/whitestork.desktop /etc/others-menu/extra_applications/0112_whitestorkgui.desktop' ; +#maemo-confirm-text /usr/share/doc/whitestorkgui/copyright + +#case $? in +#0)su $USER -c 'gconftool-2 --type bool --set /apps/maemo/WhiteStork/configuration/licence true';; + # maemo-select-menu-location whitestork.desktop +#1)su $USER -c 'gconftool-2 --type bool --set /apps/maemo/WhiteStork/configuration/licence false';; +#esac +maemo-select-menu-location whitestork.desktop + +exit 0 + +# End automatically added section diff --git a/data/package_contents/whitestorkgui/DEBIAN/postrm b/data/package_contents/whitestorkgui/DEBIAN/postrm new file mode 100755 index 0000000..75a3c55 --- /dev/null +++ b/data/package_contents/whitestorkgui/DEBIAN/postrm @@ -0,0 +1,4 @@ +#!/bin/sh + +echo -e "Postremoving actions..." +su $USER -c 'rm -f /etc/others-menu/extra_applications/0112_whitestorkgui.desktop' ; \ No newline at end of file diff --git a/data/package_contents/whitestorkgui/DEBIAN/preinst b/data/package_contents/whitestorkgui/DEBIAN/preinst new file mode 100755 index 0000000..302910b --- /dev/null +++ b/data/package_contents/whitestorkgui/DEBIAN/preinst @@ -0,0 +1,3 @@ +#!/bin/sh + +echo -e "Preinstallation actions..." diff --git a/data/package_contents/whitestorkgui/DEBIAN/prerm b/data/package_contents/whitestorkgui/DEBIAN/prerm new file mode 100755 index 0000000..46ce117 --- /dev/null +++ b/data/package_contents/whitestorkgui/DEBIAN/prerm @@ -0,0 +1,7 @@ +#!/bin/sh + +echo -e "Preremoving actions..." + + + +# End automatically added section diff --git a/data/package_contents/whitestorkplugins/DEBIAN/control b/data/package_contents/whitestorkplugins/DEBIAN/control new file mode 100644 index 0000000..63cb47b --- /dev/null +++ b/data/package_contents/whitestorkplugins/DEBIAN/control @@ -0,0 +1,25 @@ +Package: whitestorkplugins +Version: +Section: user/office +Priority: optional +Architecture: all +Installed-Size: +Depends: libexpat1 (>= 1.95.8) +Maintainer: ComArch S.A. +Description: Parsing engines for WhiteStork Multilingual Dictionary + This package enables the use of XDXF and stardict dictionaries. Additional information about the XDXF format can be found here: xdxf.sourceforge.net. + Copyright 2006, ComArch S.A. +Maemo-Icon-26: + iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI + WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1wEJDBUeRyfCHgAAAk5JREFUSMftlk9LVGEUxn937lzv + nROjZDOpYdg/E3XQoiCEsk1R0CosXPUJ2rVp0baP0Aco2rRxE0FhRFGRmzbRH9IW0SJBLFKpR67j + eFv4DkyTOtMoLaKzet/3POc8nHuf+7wX/rXwGqyLgHNuHUdRNJFKpeYlLa9X4NfZuAXYAWSjKOpK + kmQoSZK7wAhwC7ji+35zEASFIAi+FItFrTXRNiAPcAT25+AQwGHo7YQ+gD2wtxXaJ0GXff+8SqUs + MA58BHLAJUAAYRimfN9/Imm2kig9BFd7YdQ1TI/CvnIyB7RWgK+H4TXF8bibZAWYcSkBYwBxHI+Y + 2XB5v947SgO95c0p6M9DD0AHtN3JZCamFxdvA4XVIwQ0A+/ddC1Aj5ntljTWsHLMrNvMBty2GTgI + WBXmuJm1bVp1ZtYNDLhp5ipSeSAAnkua2Sp5Y2ZZ4IIj+wBMSiquh083QNAGDALHHEE38G4jkron + MrPTQNbhZ4BXVZAunGiAJeCRJNVNZGYF1+ChpJPAV+BFjZpgVbD8kPS0JpEjKUqarDjuAC669Sfg + fsUUv0Qmk9npeV6/pMe1iEZqfAtp4Kzr0bRGfiUMw3bf929KWkxvwpCXgXsbAXzfP1P209QGuFkz + y29C/k1AIOl7PWIYBmLgpaTSH5D0ONk/KF8dXh1FncBR9wjeAguSpqsw24F8LkkKyxDOed5rSW8a + dgYz63PGuasq9e3G0tLgiVLp2YEkWfBgasssqDqS1atjCojXIkr9rX+G/0QNR3oLe30G5p1j/BY/ + AaknsXLnUsw8AAAAAElFTkSuQmCC diff --git a/data/package_contents/whitestorkplugins/DEBIAN/postinst b/data/package_contents/whitestorkplugins/DEBIAN/postinst new file mode 100755 index 0000000..43847fa --- /dev/null +++ b/data/package_contents/whitestorkplugins/DEBIAN/postinst @@ -0,0 +1,13 @@ +#!/bin/sh + +echo -e "Postinstalling actions..." + +if [ "$1" != "upgrade" ] +then +# End automatically added section + +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Engines/xdxf/path "/usr/lib/WhiteStork/engine_xdxf.so"' +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Engines/stardict/path "/usr/lib/WhiteStork/engine_stardict.so"' + +fi +# End automatically added section diff --git a/data/package_contents/whitestorkplugins/DEBIAN/postrm b/data/package_contents/whitestorkplugins/DEBIAN/postrm new file mode 100755 index 0000000..36c6660 --- /dev/null +++ b/data/package_contents/whitestorkplugins/DEBIAN/postrm @@ -0,0 +1,3 @@ +#!/bin/sh + +echo -e "Postremoving actions..." diff --git a/data/package_contents/whitestorkplugins/DEBIAN/preinst b/data/package_contents/whitestorkplugins/DEBIAN/preinst new file mode 100755 index 0000000..302910b --- /dev/null +++ b/data/package_contents/whitestorkplugins/DEBIAN/preinst @@ -0,0 +1,3 @@ +#!/bin/sh + +echo -e "Preinstallation actions..." diff --git a/data/package_contents/whitestorkplugins/DEBIAN/prerm b/data/package_contents/whitestorkplugins/DEBIAN/prerm new file mode 100755 index 0000000..1edb424 --- /dev/null +++ b/data/package_contents/whitestorkplugins/DEBIAN/prerm @@ -0,0 +1,12 @@ +#!/bin/sh + +echo -e "Preremoving actions..." + +if [ "$1" != "upgrade" ] +then + echo -e -n "Removing gconf configuration..\n" + su $USER -c 'gconftool-2 --recursive-unset /apps/maemo/WhiteStork/Engines' +fi + + +# End automatically added section diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..dbf5ee3 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,20 @@ +whitestork (1.1.0-1) unstable; urgency=low + + * plugin for home applet "Internet Search" - search in mDictionary + * change Copyright 2006 into Copyright 2006-2007 in copyrigth file + * some info banners have been claryfied + * cleaning translation after unsuccessful new search fixed + + -- unknown Tue, 24 Jul 2007 15:27:00 +0300 + +whitestork (1.0.1-1) unstable; urgency=low + + * Minor packaging update. No code changes. + + -- unknown Sun, 29 Apr 2007 19:30:47 +0300 + +whitestork (1.0.0-1) unstable; urgency=low + + * Initial Release. + + -- unknown Thu, 29 Mar 2007 14:14:47 +0200 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..b8626c4 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +4 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..9e7b4fc --- /dev/null +++ b/debian/control @@ -0,0 +1,89 @@ +Source: whitestork +Section: user/office +Priority: extra +Maintainer: Krzysztof Sasiak +Build-Depends: debhelper (>= 4), libdb1-dev, libosso-dev (>= 1.20-1), libgtk2.0-dev (>= 2.6.10), gtkhtml-dev (>= 3.9.1), hildon-libs-dev (>= 0.14.11), libart-2.0-dev (>= 2.3.17), hildon-fm-dev (>= 1.24), libbz2-dev (>=1.0.3) +Standards-Version: 3.6.1 + +Package: whitestorkgui +Section: user/office +Priority: optional +Architecture: any +Depends: ${shlibs:Depends}, whitestork (>= 1.1.0-1) +Description: User interface for mDictionary + WhiteStork Multilingual Dictionary is a very functional + application allowing the use of many dictionary engines. + You can either download them from our homepage at + http://garage.maemo.org, or write your own, provided + that You stick to the API (also available on our homepage). + The graphical user interface of our application can also + be replaced by a product of Your own programming skills. + This package contains all three whitestork modules that is: + gui, engines and plugins. + Copyright 2006, ComArch S.A. +XB-Maemo-Icon-26: + iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI + WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1wEJDBUeRyfCHgAAAk5JREFUSMftlk9LVGEUxn937lzv + nROjZDOpYdg/E3XQoiCEsk1R0CosXPUJ2rVp0baP0Aco2rRxE0FhRFGRmzbRH9IW0SJBLFKpR67j + eFv4DkyTOtMoLaKzet/3POc8nHuf+7wX/rXwGqyLgHNuHUdRNJFKpeYlLa9X4NfZuAXYAWSjKOpK + kmQoSZK7wAhwC7ji+35zEASFIAi+FItFrTXRNiAPcAT25+AQwGHo7YQ+gD2wtxXaJ0GXff+8SqUs + MA58BHLAJUAAYRimfN9/Imm2kig9BFd7YdQ1TI/CvnIyB7RWgK+H4TXF8bibZAWYcSkBYwBxHI+Y + 2XB5v947SgO95c0p6M9DD0AHtN3JZCamFxdvA4XVIwQ0A+/ddC1Aj5ntljTWsHLMrNvMBty2GTgI + WBXmuJm1bVp1ZtYNDLhp5ipSeSAAnkua2Sp5Y2ZZ4IIj+wBMSiquh083QNAGDALHHEE38G4jkron + MrPTQNbhZ4BXVZAunGiAJeCRJNVNZGYF1+ChpJPAV+BFjZpgVbD8kPS0JpEjKUqarDjuAC669Sfg + fsUUv0Qmk9npeV6/pMe1iEZqfAtp4Kzr0bRGfiUMw3bf929KWkxvwpCXgXsbAXzfP1P209QGuFkz + y29C/k1AIOl7PWIYBmLgpaTSH5D0ONk/KF8dXh1FncBR9wjeAguSpqsw24F8LkkKyxDOed5rSW8a + dgYz63PGuasq9e3G0tLgiVLp2YEkWfBgasssqDqS1atjCojXIkr9rX+G/0QNR3oLe30G5p1j/BY/ + AaknsXLnUsw8AAAAAElFTkSuQmCC + +Package: whitestork +Section: user/office +Priority: optional +Architecture: any +Depends: ${shlibs:Depends} +Description: Multilingual dictionary. + WhiteStork Multilingual Dictionary is a very functional + application allowing the use of many dictionary engines. + You can either download them from our homepage at + http://garage.maemo.org, or write your own, provided + that You stick to the API (also available on our homepage). + The graphical user interface of our application can also + be replaced by a product of Your own programming skills. + This package contains all three whitestork modules that is: + gui, engines and plugins. + Copyright 2006, ComArch S.A. +XB-Maemo-Icon-26: + iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI + WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1wEJDBUeRyfCHgAAAk5JREFUSMftlk9LVGEUxn937lzv + nROjZDOpYdg/E3XQoiCEsk1R0CosXPUJ2rVp0baP0Aco2rRxE0FhRFGRmzbRH9IW0SJBLFKpR67j + eFv4DkyTOtMoLaKzet/3POc8nHuf+7wX/rXwGqyLgHNuHUdRNJFKpeYlLa9X4NfZuAXYAWSjKOpK + kmQoSZK7wAhwC7ji+35zEASFIAi+FItFrTXRNiAPcAT25+AQwGHo7YQ+gD2wtxXaJ0GXff+8SqUs + MA58BHLAJUAAYRimfN9/Imm2kig9BFd7YdQ1TI/CvnIyB7RWgK+H4TXF8bibZAWYcSkBYwBxHI+Y + 2XB5v947SgO95c0p6M9DD0AHtN3JZCamFxdvA4XVIwQ0A+/ddC1Aj5ntljTWsHLMrNvMBty2GTgI + WBXmuJm1bVp1ZtYNDLhp5ipSeSAAnkua2Sp5Y2ZZ4IIj+wBMSiquh083QNAGDALHHEE38G4jkron + MrPTQNbhZ4BXVZAunGiAJeCRJNVNZGYF1+ChpJPAV+BFjZpgVbD8kPS0JpEjKUqarDjuAC669Sfg + fsUUv0Qmk9npeV6/pMe1iEZqfAtp4Kzr0bRGfiUMw3bf929KWkxvwpCXgXsbAXzfP1P209QGuFkz + y29C/k1AIOl7PWIYBmLgpaTSH5D0ONk/KF8dXh1FncBR9wjeAguSpqsw24F8LkkKyxDOed5rSW8a + dgYz63PGuasq9e3G0tLgiVLp2YEkWfBgasssqDqS1atjCojXIkr9rX+G/0QNR3oLe30G5p1j/BY/ + AaknsXLnUsw8AAAAAElFTkSuQmCC + +Package: whitestorkplugins +Section: user/office +Priority: optional +Architecture: any +Depends: ${shlibs:Depends}, whitestork (>= 1.1.0-1) +Description: Dictionary plugins for mDictionary +XB-Maemo-Icon-26: + iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI + WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1wEJDBUeRyfCHgAAAk5JREFUSMftlk9LVGEUxn937lzv + nROjZDOpYdg/E3XQoiCEsk1R0CosXPUJ2rVp0baP0Aco2rRxE0FhRFGRmzbRH9IW0SJBLFKpR67j + eFv4DkyTOtMoLaKzet/3POc8nHuf+7wX/rXwGqyLgHNuHUdRNJFKpeYlLa9X4NfZuAXYAWSjKOpK + kmQoSZK7wAhwC7ji+35zEASFIAi+FItFrTXRNiAPcAT25+AQwGHo7YQ+gD2wtxXaJ0GXff+8SqUs + MA58BHLAJUAAYRimfN9/Imm2kig9BFd7YdQ1TI/CvnIyB7RWgK+H4TXF8bibZAWYcSkBYwBxHI+Y + 2XB5v947SgO95c0p6M9DD0AHtN3JZCamFxdvA4XVIwQ0A+/ddC1Aj5ntljTWsHLMrNvMBty2GTgI + WBXmuJm1bVp1ZtYNDLhp5ipSeSAAnkua2Sp5Y2ZZ4IIj+wBMSiquh083QNAGDALHHEE38G4jkron + MrPTQNbhZ4BXVZAunGiAJeCRJNVNZGYF1+ChpJPAV+BFjZpgVbD8kPS0JpEjKUqarDjuAC669Sfg + fsUUv0Qmk9npeV6/pMe1iEZqfAtp4Kzr0bRGfiUMw3bf929KWkxvwpCXgXsbAXzfP1P209QGuFkz + y29C/k1AIOl7PWIYBmLgpaTSH5D0ONk/KF8dXh1FncBR9wjeAguSpqsw24F8LkkKyxDOed5rSW8a + dgYz63PGuasq9e3G0tLgiVLp2YEkWfBgasssqDqS1atjCojXIkr9rX+G/0QNR3oLe30G5p1j/BY/ + AaknsXLnUsw8AAAAAElFTkSuQmCC \ No newline at end of file diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..83db946 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,15 @@ +This package was debianized by Krzysztof Sasiak on +Thu, 29 Mar 2007 13:28:58 +0200. + +It was downloaded from https://garage.maemo.org + +Upstream Author: WhiteStork development team + +Copyright: Comarch 2006-2007 + +License: + +All components are either under the GPL or LGPL. The complete text of the GPL and LGPL licenses can be found in the /usr/share/common-licenses/GPL and /usr/share/common-licenses/LGPL files. + +The Debian packaging is (C) 2007, Krzysiek Sasiak and +is licensed under the GPL, see `/usr/share/common-licenses/GPL'. diff --git a/debian/docs b/debian/docs new file mode 100644 index 0000000..e69de29 diff --git a/debian/files b/debian/files new file mode 100644 index 0000000..3709a20 --- /dev/null +++ b/debian/files @@ -0,0 +1,3 @@ +whitestorkgui_1.1.0-1_armel.deb user/office optional +whitestork_1.1.0-1_armel.deb user/office optional +whitestorkplugins_1.1.0-1_armel.deb user/office optional diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..3fc742e --- /dev/null +++ b/debian/rules @@ -0,0 +1,100 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# GNU copyright 1997 to 1999 by Joey Hess. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + + + + +CFLAGS = -Wall -g + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 +else + CFLAGS += -O2 +endif +ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) + INSTALL_PROGRAM += -s +endif + +configure: configure-stamp +configure-stamp: + dh_testdir + # Add here commands to configure the package. + + touch configure-stamp + + +build: build-stamp + +build-stamp: configure-stamp + dh_testdir + + # Add here commands to compile the package. + $(MAKE) + #/usr/bin/docbook-to-man debian/whitestork.sgml > whitestork.1 + + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + # Add here commands to clean up after the build process. + -$(MAKE) clean + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/whitestork. + $(MAKE) install-manager DESTDIR=$(CURDIR)/debian/whitestork + $(MAKE) install-gui DESTDIR=$(CURDIR)/debian/whitestorkgui + $(MAKE) install-plugins DESTDIR=$(CURDIR)/debian/whitestorkplugins + + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs +# dh_installexamples +# dh_install +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_installinit +# dh_installcron +# dh_installinfo +# dh_installman +# dh_link + dh_strip + dh_compress + dh_fixperms +# dh_perl +# dh_python +# dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/debian/whitestork.postinst b/debian/whitestork.postinst new file mode 100755 index 0000000..6fb9e91 --- /dev/null +++ b/debian/whitestork.postinst @@ -0,0 +1,18 @@ +#!/bin/sh + +echo -e "Postinstalling actions..." + +if [ "$1" != "upgrade" ] +then +# End automatically added section +echo -e "Creating 'bookmarks' dictionary" +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Engines/bookmarks/path "/usr/lib/WhiteStork/ws_bookmark.so"' +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/bookmarks/name "Bookmarks"' +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/bookmarks/path "/usr/share/WhiteStork/dictionaries/bookmarks"' +su $USER -c 'gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/bookmarks/active false' +su $USER -c 'gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/bookmarks/optimized true' + +echo -e "Changing privilages" +chmod -R 0777 /usr/share/WhiteStork/dictionaries + +fi diff --git a/debian/whitestork.prerm b/debian/whitestork.prerm new file mode 100755 index 0000000..6279e7f --- /dev/null +++ b/debian/whitestork.prerm @@ -0,0 +1,14 @@ +#!/bin/sh + +echo -e "Preremoving actions..." + +#su $USER -c 'rm -rf /usr/share/WhiteStork' + +if [ "$1" != "upgrade" ] +then + echo -e -n "Removing gconf configuration..\n" + su $USER -c 'gconftool-2 --recursive-unset /apps/maemo/WhiteStork/Dictionaries' + su $USER -c 'gconftool-2 --recursive-unset /apps/maemo/WhiteStork/Engines' +fi + +# End automatically added section diff --git a/debian/whitestork.substvars b/debian/whitestork.substvars new file mode 100644 index 0000000..fb706ed --- /dev/null +++ b/debian/whitestork.substvars @@ -0,0 +1 @@ +shlibs:Depends=libbz2-1.0, libc6 (>= 2.3.5-1), libdb1, libdbus-1-2 (>= 0.61), libdbus-glib-1-2 (>= 0.61), libgconf2-6 (>= 2.6.4.15), libglib2.0-0 (>= 2.8.6-1osso1), libosso1 (>= 1.20-1) diff --git a/debian/whitestork/DEBIAN/control b/debian/whitestork/DEBIAN/control new file mode 100644 index 0000000..8f4cbcc --- /dev/null +++ b/debian/whitestork/DEBIAN/control @@ -0,0 +1,33 @@ +Package: whitestork +Version: 1.1.0-1 +Section: user/office +Priority: optional +Architecture: armel +Depends: libbz2-1.0, libc6 (>= 2.3.5-1), libdb1, libdbus-1-2 (>= 0.61), libdbus-glib-1-2 (>= 0.61), libgconf2-6 (>= 2.6.4.15), libglib2.0-0 (>= 2.8.6-1osso1), libosso1 (>= 1.20-1) +Installed-Size: 164 +Maintainer: Krzysztof Sasiak +Description: Multilingual dictionary. + WhiteStork Multilingual Dictionary is a very functional + application allowing the use of many dictionary engines. + You can either download them from our homepage at + http://garage.maemo.org, or write your own, provided + that You stick to the API (also available on our homepage). + The graphical user interface of our application can also + be replaced by a product of Your own programming skills. + This package contains all three whitestork modules that is: + gui, engines and plugins. + Copyright 2006, ComArch S.A. +Maemo-Icon-26: + iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI + WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1wEJDBUeRyfCHgAAAk5JREFUSMftlk9LVGEUxn937lzv + nROjZDOpYdg/E3XQoiCEsk1R0CosXPUJ2rVp0baP0Aco2rRxE0FhRFGRmzbRH9IW0SJBLFKpR67j + eFv4DkyTOtMoLaKzet/3POc8nHuf+7wX/rXwGqyLgHNuHUdRNJFKpeYlLa9X4NfZuAXYAWSjKOpK + kmQoSZK7wAhwC7ji+35zEASFIAi+FItFrTXRNiAPcAT25+AQwGHo7YQ+gD2wtxXaJ0GXff+8SqUs + MA58BHLAJUAAYRimfN9/Imm2kig9BFd7YdQ1TI/CvnIyB7RWgK+H4TXF8bibZAWYcSkBYwBxHI+Y + 2XB5v947SgO95c0p6M9DD0AHtN3JZCamFxdvA4XVIwQ0A+/ddC1Aj5ntljTWsHLMrNvMBty2GTgI + WBXmuJm1bVp1ZtYNDLhp5ipSeSAAnkua2Sp5Y2ZZ4IIj+wBMSiquh083QNAGDALHHEE38G4jkron + MrPTQNbhZ4BXVZAunGiAJeCRJNVNZGYF1+ChpJPAV+BFjZpgVbD8kPS0JpEjKUqarDjuAC669Sfg + fsUUv0Qmk9npeV6/pMe1iEZqfAtp4Kzr0bRGfiUMw3bf929KWkxvwpCXgXsbAXzfP1P209QGuFkz + y29C/k1AIOl7PWIYBmLgpaTSH5D0ONk/KF8dXh1FncBR9wjeAguSpqsw24F8LkkKyxDOed5rSW8a + dgYz63PGuasq9e3G0tLgiVLp2YEkWfBgasssqDqS1atjCojXIkr9rX+G/0QNR3oLe30G5p1j/BY/ + AaknsXLnUsw8AAAAAElFTkSuQmCC diff --git a/debian/whitestork/DEBIAN/md5sums b/debian/whitestork/DEBIAN/md5sums new file mode 100644 index 0000000..a1418c9 --- /dev/null +++ b/debian/whitestork/DEBIAN/md5sums @@ -0,0 +1,8 @@ +5f067bdec12d9cce14eda5407d62d0bb usr/lib/WhiteStork/ws_bookmark.so +6a5e2f1d820c3e845371a0096b21f441 usr/bin/WhiteStorkManager +9a2485023a17cefd2c2f671e88bfcd1e usr/share/dbus-1/services/org.maemo.WhiteStorkManager.service +de80b8431d0ebcfa6a57137f5714d468 usr/share/WhiteStork/dictionaries/bookmarks/bm_words.db +038c56e7cf13042b989fc3410b936de0 usr/share/WhiteStork/dictionaries/bookmarks/bm_trans.db +a31f5e3654fffd3a988ece3fe4804fed usr/share/doc/whitestork/changelog.Debian.gz +29b17cf44468f9ec3912a102c2b260f1 usr/share/doc/whitestork/copyright +a83292b75daf61fd8fcda3a73cbd1e5f usr/share/doc/whitestork/changelog.gz diff --git a/debian/whitestork/DEBIAN/postinst b/debian/whitestork/DEBIAN/postinst new file mode 100755 index 0000000..6fb9e91 --- /dev/null +++ b/debian/whitestork/DEBIAN/postinst @@ -0,0 +1,18 @@ +#!/bin/sh + +echo -e "Postinstalling actions..." + +if [ "$1" != "upgrade" ] +then +# End automatically added section +echo -e "Creating 'bookmarks' dictionary" +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Engines/bookmarks/path "/usr/lib/WhiteStork/ws_bookmark.so"' +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/bookmarks/name "Bookmarks"' +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/bookmarks/path "/usr/share/WhiteStork/dictionaries/bookmarks"' +su $USER -c 'gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/bookmarks/active false' +su $USER -c 'gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/bookmarks/optimized true' + +echo -e "Changing privilages" +chmod -R 0777 /usr/share/WhiteStork/dictionaries + +fi diff --git a/debian/whitestork/DEBIAN/prerm b/debian/whitestork/DEBIAN/prerm new file mode 100755 index 0000000..6279e7f --- /dev/null +++ b/debian/whitestork/DEBIAN/prerm @@ -0,0 +1,14 @@ +#!/bin/sh + +echo -e "Preremoving actions..." + +#su $USER -c 'rm -rf /usr/share/WhiteStork' + +if [ "$1" != "upgrade" ] +then + echo -e -n "Removing gconf configuration..\n" + su $USER -c 'gconftool-2 --recursive-unset /apps/maemo/WhiteStork/Dictionaries' + su $USER -c 'gconftool-2 --recursive-unset /apps/maemo/WhiteStork/Engines' +fi + +# End automatically added section diff --git a/debian/whitestork/usr/bin/WhiteStorkManager b/debian/whitestork/usr/bin/WhiteStorkManager new file mode 100755 index 0000000000000000000000000000000000000000..04c841293706e5766152518e3f8f33eb47f144b0 GIT binary patch literal 36804 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 Ozy-K(=!)uR^*;cO<>+Jp literal 0 HcmV?d00001 diff --git a/debian/whitestork/usr/share/WhiteStork/dictionaries/bookmarks/bm_trans.db b/debian/whitestork/usr/share/WhiteStork/dictionaries/bookmarks/bm_trans.db new file mode 100644 index 0000000000000000000000000000000000000000..7abe57a73c139b1959fe8851353254f053fa1320 GIT binary patch literal 8192 zcmeI#yA6OK6a~=dug1#S6r8A3o!SV41c0^CsXPRDsHF-6H*w>$e=oCF9EAV7cs z0RjXF5FkK+z%K-bZi=z=Epp1KyHp7fAV7cs0RjXF5FkK+0D(^l%;mLpwLBmH3rWrb AQIGPeOjIx-(V*| zfB*pk1PBlyK!5-N0t9{`P-M3#V;fhh~7cKS#1poj5 literal 0 HcmV?d00001 diff --git a/debian/whitestork/usr/share/dbus-1/services/org.maemo.WhiteStorkManager.service b/debian/whitestork/usr/share/dbus-1/services/org.maemo.WhiteStorkManager.service new file mode 100644 index 0000000..92c3155 --- /dev/null +++ b/debian/whitestork/usr/share/dbus-1/services/org.maemo.WhiteStorkManager.service @@ -0,0 +1,4 @@ +# Sample service description file +[D-BUS Service] +Name=org.maemo.WhiteStorkManager +Exec=/usr/bin/WhiteStorkManager diff --git a/debian/whitestork/usr/share/doc/whitestork/changelog.Debian.gz b/debian/whitestork/usr/share/doc/whitestork/changelog.Debian.gz new file mode 100644 index 0000000000000000000000000000000000000000..3db3bb9f92e444ca6245957cd043d0d334494df4 GIT binary patch literal 406 zcmV;H0crjpiwFq*0H#I)17m1mZf9j|Z)YwY@lhkV|4X`*Fb0*hDe;(8IgBsw-92 z?;&$cxOMaya_ETl;j8mwQ2?C7;BsdfS|7mpJpm4bqXcL7oG7qV8^WN?8I%y`3PioX zvpQMN7!I?EHpm^ptsf4-b|%3>sZSzI{^YEbX*D_M=i_9cwT@@5Rb{X)kcu8KaI`g8E1{JILk)Hj3fKv35)OPMxp`$0Iw*? A6aWAK literal 0 HcmV?d00001 diff --git a/debian/whitestork/usr/share/doc/whitestork/changelog.gz b/debian/whitestork/usr/share/doc/whitestork/changelog.gz new file mode 100644 index 0000000000000000000000000000000000000000..f0230f3da1b4dc94f913e00ba6dbc125f16b8be0 GIT binary patch literal 107 zcmV-x0F?h9iwFq$?7Bt*17m1mZf9j|Z)X52&&VuEEiTC~%2v=Y&@ on +Thu, 29 Mar 2007 13:28:58 +0200. + +It was downloaded from https://garage.maemo.org + +Upstream Author: WhiteStork development team + +Copyright: Comarch 2006-2007 + +License: + +All components are either under the GPL or LGPL. The complete text of the GPL and LGPL licenses can be found in the /usr/share/common-licenses/GPL and /usr/share/common-licenses/LGPL files. + +The Debian packaging is (C) 2007, Krzysiek Sasiak and +is licensed under the GPL, see `/usr/share/common-licenses/GPL'. diff --git a/debian/whitestorkgui.postinst b/debian/whitestorkgui.postinst new file mode 100755 index 0000000..02a0e3b --- /dev/null +++ b/debian/whitestorkgui.postinst @@ -0,0 +1,25 @@ +#!/bin/sh + +echo -e "Postinstalling actions..." + +if [ "$1" != "upgrade" ] +then +# End automatically added section +echo -e "Selecting menu location" +maemo-select-menu-location whitestork.desktop + +if [ -f /usr/share/applications/uri-action-defaults.list ] +then + if [ -z `grep 'mdict=hildon-whitestork.desktop' /usr/share/applications/uri-action-defaults.list` ] + then + echo -e "Adding mdict URI action - uri-action-defaults.list" + echo -en "\nmdict=hildon-whitestork.desktop\n" >> /usr/share/applications/uri-action-defaults.list + fi + if [ -z `grep 'mdict=hildon-whitestork.desktop' /usr/share/applications/schemeinfo.cache` ] + then + echo -e "Adding mdict URI action - schemeinfo.cache" + echo -en "\nmdict=hildon-whitestork.desktop\n" >> /usr/share/applications/schemeinfo.cache + fi +fi + +fi diff --git a/debian/whitestorkgui.prerm b/debian/whitestorkgui.prerm new file mode 100755 index 0000000..fab7fbb --- /dev/null +++ b/debian/whitestorkgui.prerm @@ -0,0 +1,32 @@ +#!/bin/sh + +echo -e "Preremoving actions..." + +#su $USER -c 'rm -rf /usr/share/WhiteStork' + +if [ "$1" != "upgrade" ] +then + echo -e -n "Removing gconf configuration..\n" + su $USER -c 'gconftool-2 --recursive-unset /apps/maemo/WhiteStork/Dictionaries' + su $USER -c 'gconftool-2 --recursive-unset /apps/maemo/WhiteStork/Engines' + + if [ -f /usr/share/applications/uri-action-defaults.list ] + then + if [ ! -z `grep 'mdict=hildon-whitestork.desktop' /usr/share/applications/uri-action-defaults.list` ] + then + echo -e "Removing mdict URI action - uri-action-defaults.list" + grep -v 'mdict=hildon-whitestork.desktop' /usr/share/applications/uri-action-defaults.list > tmp + cat tmp > /usr/share/applications/uri-action-defaults.list + fi + + if [ ! -z `grep 'mdict=hildon-whitestork.desktop' /usr/share/applications/schemeinfo.cache` ] + then + echo -e "Removing mdict URI action - schemeinfo.cache" + grep -v 'mdict=hildon-whitestork.desktop' /usr/share/applications/schemeinfo.cache > tmp + cat tmp > /usr/share/applications/schemeinfo.cache + rm -fr tmp + fi + fi +fi + +# End automatically added section diff --git a/debian/whitestorkgui.substvars b/debian/whitestorkgui.substvars new file mode 100644 index 0000000..5877695 --- /dev/null +++ b/debian/whitestorkgui.substvars @@ -0,0 +1 @@ +shlibs:Depends=gtkhtml0, hildon-fm1 (>= 1.14), hildon-libs0 (>= 0.14.11-1), libart-2.0-2 (>= 2.3.16), libatk1.0-0 (>= 1.9.0), libc6 (>= 2.3.5-1), libdbus-1-2 (>= 0.61), libdbus-glib-1-2 (>= 0.61), libgconf2-6 (>= 2.6.4.15), libglib2.0-0 (>= 2.8.6-1osso1), libgtk2.0-0 (>= 2:2.6.10-1.osso8), libosso1 (>= 1.20-1), libpango1.0-0 (>= 1.8.1) diff --git a/debian/whitestorkgui/DEBIAN/control b/debian/whitestorkgui/DEBIAN/control new file mode 100644 index 0000000..3187c10 --- /dev/null +++ b/debian/whitestorkgui/DEBIAN/control @@ -0,0 +1,34 @@ +Package: whitestorkgui +Version: 1.1.0-1 +Section: user/office +Priority: optional +Architecture: armel +Depends: gtkhtml0, hildon-fm1 (>= 1.14), hildon-libs0 (>= 0.14.11-1), libart-2.0-2 (>= 2.3.16), libatk1.0-0 (>= 1.9.0), libc6 (>= 2.3.5-1), libdbus-1-2 (>= 0.61), libdbus-glib-1-2 (>= 0.61), libgconf2-6 (>= 2.6.4.15), libglib2.0-0 (>= 2.8.6-1osso1), libgtk2.0-0 (>= 2:2.6.10-1.osso8), libosso1 (>= 1.20-1), libpango1.0-0 (>= 1.8.1), whitestork (>= 1.1.0-1) +Installed-Size: 232 +Maintainer: Krzysztof Sasiak +Source: whitestork +Description: User interface for mDictionary + WhiteStork Multilingual Dictionary is a very functional + application allowing the use of many dictionary engines. + You can either download them from our homepage at + http://garage.maemo.org, or write your own, provided + that You stick to the API (also available on our homepage). + The graphical user interface of our application can also + be replaced by a product of Your own programming skills. + This package contains all three whitestork modules that is: + gui, engines and plugins. + Copyright 2006, ComArch S.A. +Maemo-Icon-26: + iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI + WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1wEJDBUeRyfCHgAAAk5JREFUSMftlk9LVGEUxn937lzv + nROjZDOpYdg/E3XQoiCEsk1R0CosXPUJ2rVp0baP0Aco2rRxE0FhRFGRmzbRH9IW0SJBLFKpR67j + eFv4DkyTOtMoLaKzet/3POc8nHuf+7wX/rXwGqyLgHNuHUdRNJFKpeYlLa9X4NfZuAXYAWSjKOpK + kmQoSZK7wAhwC7ji+35zEASFIAi+FItFrTXRNiAPcAT25+AQwGHo7YQ+gD2wtxXaJ0GXff+8SqUs + MA58BHLAJUAAYRimfN9/Imm2kig9BFd7YdQ1TI/CvnIyB7RWgK+H4TXF8bibZAWYcSkBYwBxHI+Y + 2XB5v947SgO95c0p6M9DD0AHtN3JZCamFxdvA4XVIwQ0A+/ddC1Aj5ntljTWsHLMrNvMBty2GTgI + WBXmuJm1bVp1ZtYNDLhp5ipSeSAAnkua2Sp5Y2ZZ4IIj+wBMSiquh083QNAGDALHHEE38G4jkron + MrPTQNbhZ4BXVZAunGiAJeCRJNVNZGYF1+ChpJPAV+BFjZpgVbD8kPS0JpEjKUqarDjuAC669Sfg + fsUUv0Qmk9npeV6/pMe1iEZqfAtp4Kzr0bRGfiUMw3bf929KWkxvwpCXgXsbAXzfP1P209QGuFkz + y29C/k1AIOl7PWIYBmLgpaTSH5D0ONk/KF8dXh1FncBR9wjeAguSpqsw24F8LkkKyxDOed5rSW8a + dgYz63PGuasq9e3G0tLgiVLp2YEkWfBgasssqDqS1atjCojXIkr9rX+G/0QNR3oLe30G5p1j/BY/ + AaknsXLnUsw8AAAAAElFTkSuQmCC diff --git a/debian/whitestorkgui/DEBIAN/md5sums b/debian/whitestorkgui/DEBIAN/md5sums new file mode 100644 index 0000000..ada6ed2 --- /dev/null +++ b/debian/whitestorkgui/DEBIAN/md5sums @@ -0,0 +1,15 @@ +e0da5879c3e3d8466356557c9091863a usr/bin/WhiteStork +b907dd078b0e37674a3027684a1b28e2 usr/share/locale/es/LC_MESSAGES/whitestork.mo +5f0984cfa09f0b804724499fe68735ed usr/share/locale/en_GB/LC_MESSAGES/whitestork.mo +20844a479f271affde8494ff7598ed90 usr/share/locale/pl_PL/LC_MESSAGES/whitestork.mo +e200a9473dfc5873b4f3d5b59b164d7f usr/share/dbus-1/services/org.maemo.WhiteStorkGui.service +4b6c65ac54436acc13b386f94e939fe4 usr/share/pixmaps/qgn_indi_search_whitestork.png +fec80a81a69379cdb5c9d984ef5b0deb usr/share/pixmaps/ws_tra.png +800fc1180d1ffb33274849798bfd3a05 usr/share/pixmaps/ws_warning_icon.png +c3179c526e679e87dd7a793f6cb00ca4 usr/share/pixmaps/ws_top.png +641156ce47d1b30662f360464b4fc00a usr/share/pixmaps/whitestork.png +49537826f9623d12201bea3edec12946 usr/share/pixmaps/whitestork_icon.png +7fa9c9cf33b8aacfe4265c26cad9cd71 usr/share/mis/whitestork-search.xml +a31f5e3654fffd3a988ece3fe4804fed usr/share/doc/whitestorkgui/changelog.Debian.gz +29b17cf44468f9ec3912a102c2b260f1 usr/share/doc/whitestorkgui/copyright +08b4422265f552fdbaf73a576e75a51a usr/share/applications/hildon/whitestork.desktop diff --git a/debian/whitestorkgui/DEBIAN/postinst b/debian/whitestorkgui/DEBIAN/postinst new file mode 100755 index 0000000..02a0e3b --- /dev/null +++ b/debian/whitestorkgui/DEBIAN/postinst @@ -0,0 +1,25 @@ +#!/bin/sh + +echo -e "Postinstalling actions..." + +if [ "$1" != "upgrade" ] +then +# End automatically added section +echo -e "Selecting menu location" +maemo-select-menu-location whitestork.desktop + +if [ -f /usr/share/applications/uri-action-defaults.list ] +then + if [ -z `grep 'mdict=hildon-whitestork.desktop' /usr/share/applications/uri-action-defaults.list` ] + then + echo -e "Adding mdict URI action - uri-action-defaults.list" + echo -en "\nmdict=hildon-whitestork.desktop\n" >> /usr/share/applications/uri-action-defaults.list + fi + if [ -z `grep 'mdict=hildon-whitestork.desktop' /usr/share/applications/schemeinfo.cache` ] + then + echo -e "Adding mdict URI action - schemeinfo.cache" + echo -en "\nmdict=hildon-whitestork.desktop\n" >> /usr/share/applications/schemeinfo.cache + fi +fi + +fi diff --git a/debian/whitestorkgui/DEBIAN/prerm b/debian/whitestorkgui/DEBIAN/prerm new file mode 100755 index 0000000..fab7fbb --- /dev/null +++ b/debian/whitestorkgui/DEBIAN/prerm @@ -0,0 +1,32 @@ +#!/bin/sh + +echo -e "Preremoving actions..." + +#su $USER -c 'rm -rf /usr/share/WhiteStork' + +if [ "$1" != "upgrade" ] +then + echo -e -n "Removing gconf configuration..\n" + su $USER -c 'gconftool-2 --recursive-unset /apps/maemo/WhiteStork/Dictionaries' + su $USER -c 'gconftool-2 --recursive-unset /apps/maemo/WhiteStork/Engines' + + if [ -f /usr/share/applications/uri-action-defaults.list ] + then + if [ ! -z `grep 'mdict=hildon-whitestork.desktop' /usr/share/applications/uri-action-defaults.list` ] + then + echo -e "Removing mdict URI action - uri-action-defaults.list" + grep -v 'mdict=hildon-whitestork.desktop' /usr/share/applications/uri-action-defaults.list > tmp + cat tmp > /usr/share/applications/uri-action-defaults.list + fi + + if [ ! -z `grep 'mdict=hildon-whitestork.desktop' /usr/share/applications/schemeinfo.cache` ] + then + echo -e "Removing mdict URI action - schemeinfo.cache" + grep -v 'mdict=hildon-whitestork.desktop' /usr/share/applications/schemeinfo.cache > tmp + cat tmp > /usr/share/applications/schemeinfo.cache + rm -fr tmp + fi + fi +fi + +# End automatically added section diff --git a/debian/whitestorkgui/usr/bin/WhiteStork b/debian/whitestorkgui/usr/bin/WhiteStork new file mode 100755 index 0000000000000000000000000000000000000000..79ca1ed93ed88d0e1a123dd30a03ad94c1c2fdd8 GIT binary patch literal 73572 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 bQ3v7L<;J;qMRNvELYx5Ho6$qq&&U4(>Rl9# literal 0 HcmV?d00001 diff --git a/debian/whitestorkgui/usr/share/applications/hildon/whitestork.desktop b/debian/whitestorkgui/usr/share/applications/hildon/whitestork.desktop new file mode 100644 index 0000000..8870c02 --- /dev/null +++ b/debian/whitestorkgui/usr/share/applications/hildon/whitestork.desktop @@ -0,0 +1,20 @@ +[Desktop Entry] +Encoding=UTF-8 +Version=1.0 +Name=WhiteStork Dictionary +Comment=Multilingual dictionary +Exec=/usr/bin/WhiteStork +X-Osso-Service=org.maemo.WhiteStorkGui +Icon=whitestork_icon +Terminal=true +Type=Application +X-HildonDesk-ShowInToolbar=true +X-Osso-Type=application/x-executable +X-Window-Icon=whitestork_icon + +X-Osso-URI-Actions=mdict; + +[X-Osso-URI-Action Handler mdict] +Method=search_home_applet +Name=uri_link_open_link +TranslationDomain=osso-uri \ No newline at end of file diff --git a/debian/whitestorkgui/usr/share/dbus-1/services/org.maemo.WhiteStorkGui.service b/debian/whitestorkgui/usr/share/dbus-1/services/org.maemo.WhiteStorkGui.service new file mode 100644 index 0000000..6eaf142 --- /dev/null +++ b/debian/whitestorkgui/usr/share/dbus-1/services/org.maemo.WhiteStorkGui.service @@ -0,0 +1,4 @@ +# Sample service description file +[D-BUS Service] +Name=org.maemo.WhiteStorkGui +Exec=/usr/bin/WhiteStork diff --git a/debian/whitestorkgui/usr/share/doc/whitestorkgui/changelog.Debian.gz b/debian/whitestorkgui/usr/share/doc/whitestorkgui/changelog.Debian.gz new file mode 100644 index 0000000000000000000000000000000000000000..3db3bb9f92e444ca6245957cd043d0d334494df4 GIT binary patch literal 406 zcmV;H0crjpiwFq*0H#I)17m1mZf9j|Z)YwY@lhkV|4X`*Fb0*hDe;(8IgBsw-92 z?;&$cxOMaya_ETl;j8mwQ2?C7;BsdfS|7mpJpm4bqXcL7oG7qV8^WN?8I%y`3PioX zvpQMN7!I?EHpm^ptsf4-b|%3>sZSzI{^YEbX*D_M=i_9cwT@@5Rb{X)kcu8KaI`g8E1{JILk)Hj3fKv35)OPMxp`$0Iw*? A6aWAK literal 0 HcmV?d00001 diff --git a/debian/whitestorkgui/usr/share/doc/whitestorkgui/copyright b/debian/whitestorkgui/usr/share/doc/whitestorkgui/copyright new file mode 100644 index 0000000..83db946 --- /dev/null +++ b/debian/whitestorkgui/usr/share/doc/whitestorkgui/copyright @@ -0,0 +1,15 @@ +This package was debianized by Krzysztof Sasiak on +Thu, 29 Mar 2007 13:28:58 +0200. + +It was downloaded from https://garage.maemo.org + +Upstream Author: WhiteStork development team + +Copyright: Comarch 2006-2007 + +License: + +All components are either under the GPL or LGPL. The complete text of the GPL and LGPL licenses can be found in the /usr/share/common-licenses/GPL and /usr/share/common-licenses/LGPL files. + +The Debian packaging is (C) 2007, Krzysiek Sasiak and +is licensed under the GPL, see `/usr/share/common-licenses/GPL'. diff --git a/debian/whitestorkgui/usr/share/locale/en_GB/LC_MESSAGES/whitestork.mo b/debian/whitestorkgui/usr/share/locale/en_GB/LC_MESSAGES/whitestork.mo new file mode 100644 index 0000000000000000000000000000000000000000..d3a086d3f1f65a078b1c40bf5a03db515b45a594 GIT binary patch literal 5367 zcmai%O^h5z6~~Le@_Qw0=-Nlw8P}4J0yVKd8 zu5owIj>m}{y4Ktf5gI~E5FFf*tLfi%J1@8e5f{%hz;BL?Z zKLUof{G2U+1N;Q)uYn&2uY(^0Z-94$Z&|(ra{Rx+`@lOeDc8FnWWR^O4}*t5u748b zJd5D{U=!s0SHK6rZ-MOpW03Rx6nqf80qy~R2YwQ~WqI$1geajr0doGM;77q(kn>*z zsb3eo7rY8`ofj-$w)H;)InOUaj(ZFI6!QJ_xe^G+tbH0pz-01vx$d zx$g5I?eQIu_V^)a>{MIPN&e_7#xpuY;cfpRwidgVg60kn_C>Qt!Wj+|NI4c{eJ#&j&!- zb00{1JPuNydGNEK2huLz1UcVJAm@4Aw%-J&-zUW1LF!jQXDlHaAjhrXg-{kv@B^T- zWgkSS2@P_+0Z6-k4}|H&%OKY1 z&i@$5ea?bBT9-i1=h%85r2U=)xt|v;UjcWa{D$RCkmG*^Qs3W#+}|H<``lt8#v+yhe2Js|ft0dhZwLF#n^WdAwKMUd;Rf?W3!$aUKw$8UlhAA#J* zvmotz4P>0W3Nr3~4W0u30UiR&Fv1)~Kl}ouJ^ln@E8;&OC(mSN@vB=ROG6;WG_609j=L56{H{ zN3;rZkqcrNM?J|`iML-s>XKxQFT2%pbE=mXk=&rAaIUcvhuzi`Z6{P+y``MC*NQzIxS^+_v@TM73Zqf-L&Wh z#bVEmtYR3>ZcbaRyL~^l-A$F3&SgrvZyLJ_Hp#!6T5opUa5LgSv}I+-Z5y3O>RP^z z)V7|wr_4$tT@$<7zQu8wX<%vFT&yzg+NoamVz296O_v`TGqTu7OX5R2pK5!l4fsiy z4GT?_$byrTeIbs2%x-}m z-BYZc;wiyiians?m_g7QBTC`E{Gv++F}j?1*efoTMBKXWC*h8ciRp8njv3O1J+7P3 zURD@mV<%Za(`?r4V-5L{#-M@nTe_S2F%NxnKsdg~TRFSdQNp%Dx;VM_V=uY%oY;#K zi?U|yB%o^K_8W-{G`2b#x8In>3-j?TW(uJ{^G@D-II{Mb<+ufmu(er?Fc&2nFNgYR z@~5rVZQm+Ld<>Sr4ALStohZfUW!qIxiNc_G^H+U4o~MpRzYHCb9-S}V_l z%EWK^v>U6MJTy6Zv|O#0t4CzDT04AXVzN3piH_wJwdHYg+wW4NzEWOTDxa>)vrDyw zxrwKi78|8`Ty?{28_ znsU1}+0!stN1m9UKjnKB9d4W~EzB)6@*P$ylcgCQ#45mo2*#RZxE}2Jt`{7at&ST; zDt_Y2YqRBJc|R()uEKI7XldsCnmpF@;*yw8eg;Uyh0z?_tW+vuHT^xn!ixDZAhYwZ zbWY49$(~;(!B@oT^rym5cHBrdk;`S`xpqa&X8Bz*zvo4<;9ikT#L`z=%Et)AtHOu{ zFW9ku*`#Z=gms9oWERomSZJCzXGQ*^u)kIAFy~d)_u8 z-zO6_ttYd<9CF?zn~?KrbSzjg>usx7%`LO7cY{e8wjBzyV>pDDk*p);+MbA1l~%GrH`1v64NvwTTl~5f_a* zL)}N?rjoIi=o-edAK{G1xZ_2+XNFLFFtx*wG`o!VpAw5|P#m8f47>5dnc2xMh2}z5 zgwo7{#d(wSk&f<$!-8s z!#I*A8D_;unmm}@80#UIFcO5>&8TPGNoo*Y^zIrj?E`Yk6Y;G2HGpm z_fWC4{UW@mDScA%4H-P^9{W^ZF Nq!(~HNm?G6;=jz~nAHFP literal 0 HcmV?d00001 diff --git a/debian/whitestorkgui/usr/share/locale/es/LC_MESSAGES/whitestork.mo b/debian/whitestorkgui/usr/share/locale/es/LC_MESSAGES/whitestork.mo new file mode 100644 index 0000000000000000000000000000000000000000..823ba0a2d36502e3ce208c00ecb1b8ad16deae08 GIT binary patch literal 5577 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 F>VI;S_4xn* literal 0 HcmV?d00001 diff --git a/debian/whitestorkgui/usr/share/locale/pl_PL/LC_MESSAGES/whitestork.mo b/debian/whitestorkgui/usr/share/locale/pl_PL/LC_MESSAGES/whitestork.mo new file mode 100644 index 0000000000000000000000000000000000000000..fbe30a2b9b9469d9b3624cbe5563e1939c9d1067 GIT binary patch literal 5430 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 UIuHyMs@`WIzjC_UD?`Tr0Bzh0O#lD@ literal 0 HcmV?d00001 diff --git a/debian/whitestorkgui/usr/share/mis/whitestork-search.xml b/debian/whitestorkgui/usr/share/mis/whitestork-search.xml new file mode 100644 index 0000000..63abce4 --- /dev/null +++ b/debian/whitestorkgui/usr/share/mis/whitestork-search.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/debian/whitestorkgui/usr/share/pixmaps/qgn_indi_search_whitestork.png b/debian/whitestorkgui/usr/share/pixmaps/qgn_indi_search_whitestork.png new file mode 100644 index 0000000000000000000000000000000000000000..482de9b92fb0eead643c197695da85fd30a0e5b2 GIT binary patch literal 1563 zcmV+$2ITpPP)oe03CEi zSad^gZEa<4bO1wgWnpw>WFU8GbZ8({Xk{QrNlj4iWF>9@00nL6xjom6xsN&p27L3a@;5EuLBm07-5-2c} zMZm#Y9XPQl&?{mKXd)m86r%Cc3-Hp**@u(8ArO&}kS*E!Pd}XJ$@4$Y>F<5d$!RGN zLI8jb!vFvP0EXR;2J(O}kjvXEC z?F%$&fB5i9NlBAZIWjS^Dj+~6l`hgq$mw(jty(pI8SfQ@5JG76_C_E0kLG6xwKO-c z0AP4%2!$Ex>7gMZ*UQUM*wok<5)`D>Xkxfr_I<^U7VY1v)NGodU<)aSlneWtPc$p3Iu)(Mo3`b zuQfFQfG2%@yAl&onMf$K+wB2({Rj<>UmeTNs|yPXemHSrrH_wNq2O=bie{5Z zr5Wkz%XM}znM?q{nWCa&1qD7nK31z00AMzooA2Do5{orzwLz~JWoDXRy}EGeQf_wk z^z?L_O0{9*Mr7ZfkRZ;@wc+^M;NV?}i4KROySLZa*Vo(AbETvN)qHpScx`ocY-D6Z zT^-SvFa`z%eY$gJbWF_Cfq_RRQ=3X9Eh_^6+-+&OQCs`$*|Xp3>j(P#xA6Jqv9ZsS zlVwur`HL5qWwZErdqW6KMq@CWZMWNHQt8RULI~l-^XD_t(;o=(H|X`e=xDUKM_pYg$>nfNMx(`IVbJNfl}cjr##^_90>PY) zkGs1Wbo%qb!P&-OHXFxrqUKh8{r-LX-o1P0i(yk!QxHOn#X_f2H>_JnH2t7FmbOzE zOlEIS&jXdJyrKdCK&R7fHe2hxdsHfQ*Y4f-TU%pdW6@Rz0BF?eEquP!Y8@UL;zmXS z0N%cRYaSbm*u1&3qXWnBls$W9Pkz0!a!$Lb=x9!O_~hi|Y$GQ;oJOM&HF}*cHZD%5 z)$-!wJv}{9X5ISrR*S{$b}#aKEfEKc#X4JD{B3?dhG75z8jWVPT4hpcjzmJCP&8^a zaex5;v>MIF+qUU-I)af-tBvFFs8p)U<=UQ*@Rv%paJ%vGaU93PBO>m$v>>C?>3s9% z4N)*LF(I$2deG4!ud3R@=M#@1H7#v>Lc$k&_dZms*=+W5UBkx5$5pMZhw}1JxPnG| zF+BX|?b~08M8xYr6r)h9(ac^b8uQ}gpFVj~BbVbiKG5HPrl?3H6aoOsuU-44v~+Z2 z1jliWS}oYW|7vL|0*#DuJl^xc!5g);Gcz;l&d%hdq#sY84qCHj_LD#zQ&Lk8A33rw zHFbJ=dRgurI<1!F}?% z5piCq?%(G{M|*jA1hd%^vDj=jqZ5SB<6$(KKZ})?l48*7=Npv@1t%oDijQfNM8hRVt{8lnv zUN55C=wc)^o5kyd=Dp^BT#hVhkA3b<>^KtqfWuO??|JgxF&SA6fr7>5H<) z_r)jY+W0zg$n0l%Z@XOBhx@rsjP%bJn(Ad+R2}nj`#&gToxYbX_qAi$8@Y{ACeItC zHhK5PoqRR7Hu~1o3LE`txmRYty25ti%t6sxOWy00=;~M&U5?!GTPbK~%G(@`*j~r9 zhpTJ^CVF2{i^ysLh^4v9qYqO%R8()?5}F>%?X47RTRA(+hkx(f>+9I_ zlns`q-b@vJ$#lK^=8MRh*STkJe(Eq2+tFmR$d`4UQh!EpqxQxxDwm?4s9c&~t9&{q z``$?>6_5D$qQUM9$|hMqsyocuH*J~haf3#~2PQW}y*{~o-*|PA-Ug97Yl1_|zjTC% z-k3Cht=cB5Jl)2Z_Af=ffaFNi&mQ?J?N6&*vW(*6 z@5~LiTR(qZ+1^}rOQv+aSIWBT>P1W9UDm}%_Z$#&+poP=iWwNqJ_;Qx9G)zAv}%f) zn{=bXBc}VABG;CrYAJt^Rk`+TOIH7fb3)Ts99wcw;Ottv>ziV14N_AldWSDre`8*U z!ZvO76BlX|pE+Dw{w3VyP0FFr8_PLFoC6o=K6L;Z%*kTdsDP5Fa0s4ApYlcYC))#- Wn#7l>)uF&-%;4$j=d#Wzp$PzdphkKC literal 0 HcmV?d00001 diff --git a/debian/whitestorkgui/usr/share/pixmaps/whitestork_icon.png b/debian/whitestorkgui/usr/share/pixmaps/whitestork_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2c3563bdcae59e515913ebd0fbdf1d63e5b90946 GIT binary patch literal 277 zcmV+w0qXvVP)|#L{VBhDH z`KKLKLEe0ae(wcEN&N<%;K<=P#fHg2xVGqTR7_bmlQ9h|^u z)pcQhn$!QIF3d__WFZDt09AbX>DV*LAR^5R`;&WACG+--?XVD93}HuriYlZiVtc5v b_J5!o#LCw#8{S%C00000NkvXXu0mjf_N#YT literal 0 HcmV?d00001 diff --git a/debian/whitestorkgui/usr/share/pixmaps/ws_top.png b/debian/whitestorkgui/usr/share/pixmaps/ws_top.png new file mode 100644 index 0000000000000000000000000000000000000000..26496e93fb2cead518ba5c350d689b423811a3fb GIT binary patch literal 280 zcmeAS@N?(olHy`uVBq!ia0vp^ObiT+6F7h*12?Z)Kak=q@Q5r1@`ON`@zUM8KS04# zo-U3d6}R3VI_=l&AklC!|N6S9u(r_D)Yr!@w2FQ>k}e|br#pHNTG;!``f{91kW z56?3ziM(t7ZgsxS$>036T1r(sTlKSv=Nk*JWr-7dj(Pap_x`nRa>?_}Pd4YOuDvF7 z*JRSNb*iPIo~tf<7U_6w((F7{e6s!U?!&VWXHWCoWHMESPoIyyJ)QmhXB!}T bU;mp~W|d7vY?OU6&{qteu6{1-oD!M?A1Tfjum)5T7d%bU(&X77<%uBn*+YQhuDfySBo ztPx`nVTAz0#4rj|hKz6_Fc2Fd^dZK}M6lBrn=AtipD|qpFg_CbXSVW@$ed@L$xnGp z5ssH>u_oCz0v_CQL%_TPtYU)Xp{!$4m?yA_eb$y7l@Af;BOE~i`M+D*KdK;QP%278 zj3M5rWRp^zoPP8^oIjsk^gdnnE`D^s+&+DM=zLc?Kh?*ZntQv~=5t=$aop<(8{(JV z;@%@&a0EL#SX4&lg15=zUF3zGzFM`pGE x1Ltr`0r~rFw{lcUO0`t3t6`{kwUX(j`U@R^<1Fp7ee3`L002ovPDHLkV1ilY;}rk^ literal 0 HcmV?d00001 diff --git a/debian/whitestorkgui/usr/share/pixmaps/ws_warning_icon.png b/debian/whitestorkgui/usr/share/pixmaps/ws_warning_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7e4f7b6e65cb1c9ba6cb352a866e6b4f98c1b763 GIT binary patch literal 781 zcmV+o1M>WdP))bJou%8_+U_?tZk>U? z$n0*&kx+f?Q8Jk{fA?BS0lZ%CKvPp)|H{e^R@W3%u{-@%2m__Oe*k7?X4ux2Xq@$| z(jy}eFm~ews_He`=lC8U92{i-2?&S7qYaJus8)Or-phey-Joa*;h-3GP-L_$ARdoL zVlAODoAnhGWdmNG1Iv0Kiz+ydLCB|!b#pJ-*MVYWi)dHd`$vWFtXyaysN;G?$y#lZGg4F$=7ba()Zg+^rL`NE&c+invweQ zO@G= 2.3.5-1), libdbus-1-2 (>= 0.61), libdbus-glib-1-2 (>= 0.61), libexpat1 (>= 1.95.8), libgconf2-6 (>= 2.6.4.15), libglib2.0-0 (>= 2.8.6-1osso1), libosso-gnomevfs2-0, zlib1g (>= 1:1.2.1) diff --git a/debian/whitestorkplugins/DEBIAN/control b/debian/whitestorkplugins/DEBIAN/control new file mode 100644 index 0000000..0ae2b8a --- /dev/null +++ b/debian/whitestorkplugins/DEBIAN/control @@ -0,0 +1,24 @@ +Package: whitestorkplugins +Version: 1.1.0-1 +Section: user/office +Priority: optional +Architecture: armel +Depends: libc6 (>= 2.3.5-1), libdbus-1-2 (>= 0.61), libdbus-glib-1-2 (>= 0.61), libexpat1 (>= 1.95.8), libgconf2-6 (>= 2.6.4.15), libglib2.0-0 (>= 2.8.6-1osso1), libosso-gnomevfs2-0, zlib1g (>= 1:1.2.1), whitestork (>= 1.1.0-1) +Installed-Size: 204 +Maintainer: Krzysztof Sasiak +Source: whitestork +Description: Dictionary plugins for mDictionary +Maemo-Icon-26: + iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI + WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1wEJDBUeRyfCHgAAAk5JREFUSMftlk9LVGEUxn937lzv + nROjZDOpYdg/E3XQoiCEsk1R0CosXPUJ2rVp0baP0Aco2rRxE0FhRFGRmzbRH9IW0SJBLFKpR67j + eFv4DkyTOtMoLaKzet/3POc8nHuf+7wX/rXwGqyLgHNuHUdRNJFKpeYlLa9X4NfZuAXYAWSjKOpK + kmQoSZK7wAhwC7ji+35zEASFIAi+FItFrTXRNiAPcAT25+AQwGHo7YQ+gD2wtxXaJ0GXff+8SqUs + MA58BHLAJUAAYRimfN9/Imm2kig9BFd7YdQ1TI/CvnIyB7RWgK+H4TXF8bibZAWYcSkBYwBxHI+Y + 2XB5v947SgO95c0p6M9DD0AHtN3JZCamFxdvA4XVIwQ0A+/ddC1Aj5ntljTWsHLMrNvMBty2GTgI + WBXmuJm1bVp1ZtYNDLhp5ipSeSAAnkua2Sp5Y2ZZ4IIj+wBMSiquh083QNAGDALHHEE38G4jkron + MrPTQNbhZ4BXVZAunGiAJeCRJNVNZGYF1+ChpJPAV+BFjZpgVbD8kPS0JpEjKUqarDjuAC669Sfg + fsUUv0Qmk9npeV6/pMe1iEZqfAtp4Kzr0bRGfiUMw3bf929KWkxvwpCXgXsbAXzfP1P209QGuFkz + y29C/k1AIOl7PWIYBmLgpaTSH5D0ONk/KF8dXh1FncBR9wjeAguSpqsw24F8LkkKyxDOed5rSW8a + dgYz63PGuasq9e3G0tLgiVLp2YEkWfBgasssqDqS1atjCojXIkr9rX+G/0QNR3oLe30G5p1j/BY/ + AaknsXLnUsw8AAAAAElFTkSuQmCC diff --git a/debian/whitestorkplugins/DEBIAN/md5sums b/debian/whitestorkplugins/DEBIAN/md5sums new file mode 100644 index 0000000..0592362 --- /dev/null +++ b/debian/whitestorkplugins/DEBIAN/md5sums @@ -0,0 +1,9 @@ +dea05c6e24388ba68bf00897dac9c7e8 usr/lib/WhiteStork/engine_stardict.so +25d99de3c763409493df8b0a9e32188f usr/lib/WhiteStork/engine_xdxf.so +7c74be6da693ae5af69b58769d0c7c53 usr/share/pixmaps/engine_xdxf_icon.png +d64b7c82ff46e12689515eac7b978f66 usr/share/WhiteStork/dictionaries/XDXFSampleDict/dict.xdxf +e89a3c84ad2a8f1dee1fe72e08e89de2 usr/share/WhiteStork/dictionaries/StarDictSampleDict/sample.idx +334e764704d44edcb5ce5c78e237feff usr/share/WhiteStork/dictionaries/StarDictSampleDict/sample.dict.dz +5b5d19617ab1378d73a72c1af032890b usr/share/WhiteStork/dictionaries/StarDictSampleDict/sample.ifo +a31f5e3654fffd3a988ece3fe4804fed usr/share/doc/whitestorkplugins/changelog.Debian.gz +29b17cf44468f9ec3912a102c2b260f1 usr/share/doc/whitestorkplugins/copyright diff --git a/debian/whitestorkplugins/DEBIAN/postinst b/debian/whitestorkplugins/DEBIAN/postinst new file mode 100755 index 0000000..4077edf --- /dev/null +++ b/debian/whitestorkplugins/DEBIAN/postinst @@ -0,0 +1,23 @@ +#!/bin/sh + +echo -e "Postinstalling actions..." + +if [ "$1" != "upgrade" ] +then +# End automatically added section +echo -e "Creating 'elements' dictionary" +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/StarDictSampleDict/name "Polish-English_Sample_Dictionary"' +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/StarDictSampleDict/path "/usr/share/WhiteStork/dictionaries/StarDictSampleDict"' +su $USER -c 'gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/StarDictSampleDict/active true' +su $USER -c 'gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/StarDictSampleDict/optimized false' +echo -e "Creating 'Polish - English Sample Dictionary' dictionary" +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/XDXFSampleDict/name "English-Polish_Sample_Dictionary"' +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Dictionaries/XDXFSampleDict/path "/usr/share/WhiteStork/dictionaries/XDXFSampleDict"' +su $USER -c 'gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/XDXFSampleDict/active true' +su $USER -c 'gconftool-2 --type bool --set /apps/maemo/WhiteStork/Dictionaries/XDXFSampleDict/optimized false' + +echo -e "Adding gconf entries for search engines" +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Engines/xdxf/path "/usr/lib/WhiteStork/engine_xdxf.so"' +su $USER -c 'gconftool-2 --type string --set /apps/maemo/WhiteStork/Engines/stardict/path "/usr/lib/WhiteStork/engine_stardict.so"' + +fi diff --git a/debian/whitestorkplugins/usr/lib/WhiteStork/engine_stardict.so b/debian/whitestorkplugins/usr/lib/WhiteStork/engine_stardict.so new file mode 100644 index 0000000000000000000000000000000000000000..78c6b057b2340615bc4a637baa09fba177642895 GIT binary patch literal 65752 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

i0> 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 literal 0 HcmV?d00001 diff --git a/debian/whitestorkplugins/usr/share/WhiteStork/dictionaries/StarDictSampleDict/sample.dict.dz b/debian/whitestorkplugins/usr/share/WhiteStork/dictionaries/StarDictSampleDict/sample.dict.dz new file mode 100644 index 0000000..f6d5541 --- /dev/null +++ b/debian/whitestorkplugins/usr/share/WhiteStork/dictionaries/StarDictSampleDict/sample.dict.dz @@ -0,0 +1 @@ +Thank you very much.WhitestorkBe careful!I would like a ticket to...I would like to change dollars.I think I am lost.What town is this?What?traveller's checksJunefortyfourteenfourfour thousandfour hundredThursdayfourthCan I get there on foot?Is there a taxi standby nearby?Is there a currency exchange office nearby?Is there a sleeping car on the train?Do you have a map of the city?May we have an extra bed?Can I pay with my credit card?Could you help me?Could you show me this on the map, please?Do you speak English?Why?Good-bye.Good night.(Goodbye at night time)Good evening.Okay.seconda lot ofmuchtwotwo thousandtwentytwenty-onetwelvetwo hundredtwicetenthtenten percentten thousandninthnineteenninenine thousandninetynine hundreddayGood day.Good morning.todayThank you.Where is the nearest...Where is the nearest bank?Where is... ?Where?DecemberHow much do I owe you?How much is it per night?How much is the fare?How old are you?What is your name?How late it is?How do I get to this address?How far is it?How?Which line goes to...?oneelevena thirdautumnIt is two in the afternoon.It is 4:30 am.It is two o'clock.It is 6:15 pm.It is one o'clock.It is three in the afternoon.It is 3:40 am.It is three o'clock.It is one in the afternoon.tomorrowWhen does it leave?When does it arrive?When?fewblanketsupperWho?What time is it?AprilsummerdoctorleftJulyNovemberFebruaryMayMy name is...I have a reservation.MarchDo you have any vacancies?Can we switch rooms?Can you show me the room?on the cornerI do not speak Polish.I do not understand.No.SundaynightsdinnerOf course.eighteight thousandeightyeighteeneight hundredOctoberplatformfirstFridayfifthfifteenfivefive minutes agofive thousandfiftyfive hundreddouble bedroomHelp!MondayRepeat, please.halfnoonrightstraight aheadPlease tell me when to get off.The bill, please.Please call me a taxi.Please speak more slowly.Please.You are welcome.private bathExcuse me.Excuse me.I am sorry.bus stationtram stationmidnightlateronceKeep the change.roll of toilet paperI understand a little.bath towelssevenseven thousandseventyseventeenseven hundredAugustseventhSaturdaytrain stationsubway stationone hundredStop!Januarysixteensixsix thousandsixtysix hundredsixthYes.nowtracksomethirdthreethree thousandthirtythirteenthree hundredone thousandWatch out!earlieryesterdaymanyspringHello.soonSeptemberAll aboard.TuesdayzeroThat's right.Agreed.wintereightha quarterI am in a hurry.breakfastWednesday \ No newline at end of file diff --git a/debian/whitestorkplugins/usr/share/WhiteStork/dictionaries/StarDictSampleDict/sample.idx b/debian/whitestorkplugins/usr/share/WhiteStork/dictionaries/StarDictSampleDict/sample.idx new file mode 100644 index 0000000000000000000000000000000000000000..e140e95d53b217bd15377dd90514ae4fd5254c48 GIT binary patch literal 4539 zcmZu#Yls|K6;8UVs;g(FCzCjdn~h0o7ZsyR6kSw&;F<(>O-Kwe?n->X?XGL5y1MH& zRn-<%po`;%s0jXW(VdN`h_64o>VQZbbY;4IfC`EaSV0j4Mg5~cRL~!O-?`P9o^=C# zQs+D8zRo?bJ7-iHRwf9mXu26s2Gh;c`|5w|XG||r3AuIrmd;FXgtOa$$@0|9wv+N6 zN>1RneD*pNXB*ve6m+AZ&V$gLJ}vW{g80~ixF|=FPNL~es0>wFiqbhKojiNJ?5ZHc zE`q8*=|-~+JrZdT(nDuWkei@V!6;H$Zr%iJ-^2>!`zF5KUZvwG7@IKN*}?`jl|Du# z2+|_boN3=@@N;@qu5s*0&u;Z1qMyeP?zQ;hurUUDO!p zEEjoq7-g}+@v?kpYXB(DcD4!~%lZES^^<$lW0mA44QOzcltH0}lbovi4}!dGk7}X% zCJC}~9I0VaiqadP^dc&aR91nEu}Lw#5;0GCLd5U{Jt~87YG4rFYN+zq6grq~@DgG< z&HhKBe{`opz%@xsY$+mO2i;@{yO2IqtY&E2>L(!}?o?={{Ha0TGpmqnA)dW#^ODAWlj z;TlU2?Rt5G4hd}=3v}qlqae#+F^N-?ClU&cj{Hf1(FXgvQpHOio?5{dWbaVXurtAwEeeYg1< zkdENOGP8R9bi(!IJk9e!{I?A4>Uso6O>D?FuRwBylGtQbJ{eFYMCib~Wv=UxAKfD# z!=VSN3Pt=uh!0aN8Dpp<*)%^1bnU!~EsEKq5zHY2z68-BipEG3w-XZ#5CdWq5q}%v z0~F)FHeq_C)&w8O?m@1TK!vH!MDd4EJWfSKe5i)nrkv&<0j~lU9fq_6Mg_wN@f*aG zG~)@SPKm}pp>bp$Ce8}Drf_$vfpY+uXHAmh;HY?<^e{*ZIl8v5^8#v}XU?vx3HD8w zaqa~y3IKKh$FGNV{ zfe8nCwjIv4rF1yIhva!y0{+)Nvd0Vxh@o8wRi-uIW-O>mh zbP!_VuS4f3!ZI~|wo~qpK{}U^oKR<(dRZOEhNY30?EV_$2*s(XCRkEBH1}^n*MU-n zcebyIszJvd@^ZW;39<-li`OPG-AL@_9U%ACUR4&6bX_t7FLOzpol@SKE8JpY_g)Bi zRbVbO&*|PPIiwDhc^~J!7N9Sn&GFs?06JqeyUnp_5;07?iy*DBPEA7YDu`dll2pid z0dNsTH*8Di$Xkz6;5Lv6*cc=}Wwyaz65t5OZ+Y&jm@9#E$nXa4sj1F!P=P zyL#EqXInZ%BoBvvq0j$ODo~cBznCcjdeN!PRD_o1pyFgin6KSbF{ib@3gTSB8v`c@hp0f2?%J?zeFLJk)F9Ue zWA@7F1oafv6g@e*U=IF1$oiE!?gQlc-u2qFyx}A1bhB3>l-PW>{tB{;auw@>$U#F_+EY+^8G!OQ0!)Ti5G%h z_PqdFS*5du?aIl4(TO>Tci*h}MJxCW{*_v=#|$5Wz^w)Ki9ZZzIm62WtK-xE1XZpo zi3I-%Fbi-*j8);(5^wQoB;uMjAvB|n1-Xjs7&Do*<#0H;87!cpY5+AJ{b zN6@8*OcmqZ+}1t;$#MasNfK|9H45@x=Bea?_hdgx*imM*Av|_UuXcZpMdpB%Q9z%5H9r=D-eZPHoeh+Ou0J KR^r$DNd5=Brswql literal 0 HcmV?d00001 diff --git a/debian/whitestorkplugins/usr/share/WhiteStork/dictionaries/StarDictSampleDict/sample.ifo b/debian/whitestorkplugins/usr/share/WhiteStork/dictionaries/StarDictSampleDict/sample.ifo new file mode 100644 index 0000000..a37e79e --- /dev/null +++ b/debian/whitestorkplugins/usr/share/WhiteStork/dictionaries/StarDictSampleDict/sample.ifo @@ -0,0 +1,6 @@ +StarDict's dict ifo file +version=2.4.2 +wordcount=209 +idxfilesize=4539 +bookname=sample +sametypesequence=m diff --git a/debian/whitestorkplugins/usr/share/WhiteStork/dictionaries/XDXFSampleDict/dict.xdxf b/debian/whitestorkplugins/usr/share/WhiteStork/dictionaries/XDXFSampleDict/dict.xdxf new file mode 100644 index 0000000..71717ee --- /dev/null +++ b/debian/whitestorkplugins/usr/share/WhiteStork/dictionaries/XDXFSampleDict/dict.xdxf @@ -0,0 +1,214 @@ + + + English - Polish dictionary + Sample dictionary with some usefull expressions. Any suggestions? Please conntact marcin.biedron@comarch.pl. This file is part of WhiteStork application. Copyright 2007, ComArch S.A. All rights reserved. + a lot of - dużo + a quarter - ćwiartka + a third - jedna trzecia + Agreed. - Zgoda. + All aboard. - Wsiadać proszę. + April - kwiecień + August - sierpień + autumn - jesień + bath towels - ręczniki + Be careful! - Bądź ostrożny! + blanket - koc + breakfast - śniadanie + bus station - przystanek autobusowy + Can I get there on foot? - Czy dojdę tam na pieszo? + Can I pay with my credit card? - Czy można płacić kartą (kredytową)? + Can we switch rooms? - Możemy zamienić pokoje? + Can you show me the room? - Możesz pokazać mi pokój? + Could you help me? - Czy mógłbyś mi pomóc? + Could you show me this on the map, please? - Czy mógłbyś pokazać mi to miejsce na mapie? + day - dzień + December - grudzień + dinner - obiad + Do you have a map of the city? - Czy masz mapę miasta? + Do you have any vacancies? - Masz wolne pokoje? + Do you speak English? - Czy mówisz po angielsku? + doctor - lekarz + double bed - podwójne łóżko + earlier - wcześniej + eight - osiem + eight hundred - osiemset + eight thousand - osiem tysięcy + eighteen - osiemnaście + eighth - ósmy + eighty - osiemdziesiąt + eleven - jedenaście + Excuse me. - Przepraszam. + Excuse me. - Przepraszam. + February - luty + few - kilka + fifteen - piętnaście + fifth - piąty + fifty - pięćdziesiąt + first - pierwszy + five - pięć + five hundred - pięćset + five minutes ago - pięć minut temu + five thousand - pięć tysiące + forty - czterdzieści + four - cztery + four hundred - czterysta + four thousand - cztery tysiące + fourteen - czternaście + fourth - czwarty + Friday - piątek + Good day. - Dzień dobry. + Good evening. - Dobry wieczór. + Good morning. - Dzień dobry. + Good night.(Goodbye at night time) - Dobranoc. + Good-bye. - Do widzenia. + half - połowa + Hello. - Witam. + Help! - Pomocy! + How do I get to this address? - Jak się dostanę pod ten adres? + How far is it? - Jak to daleko? + How late it is? - Jak późno już jest? + How much do I owe you? - Ile jestem winny? + How much is it per night? - Ile kosztuje jedna noc? + How much is the fare? - Ile kosztuje przejazd? + How old are you? - Ile masz lat? + How? - Jak? + I am in a hurry. - Śpieszy mi się. + I am sorry. - Przykro mi. + I do not speak Polish. - Nie mówię po polsku. + I do not understand. - Nie rozumiem. + I have a reservation. - Mam rezerwację + I think I am lost. - Chyba się zgubiłem. + I understand a little. - Rozumiem trochę. + I would like a ticket to... - Chciałbym bilet do... + I would like to change dollars. - Chciałbym wymienić dolary. + Is there a currency exchange office nearby? - Czy jest tam kantor wymiany walut? + Is there a sleeping car on the train? - Czy jest tam wagon sypialny? + Is there a taxi standby nearby? - Czy jest tam blisko postój taksówek? + It is 3:40 am. - Jest trzecia czterdzieści. + It is 4:30 am. - Jest czwarta czterdzieści. + It is 6:15 pm. - Jest osiemnasta piętnaście. + It is one in the afternoon. - Jest trzynasta. + It is one o'clock. - Jest pierwsza. + It is three in the afternoon. - Jest piętnasta. + It is three o'clock. - Jest trzecia. + It is two in the afternoon. - Jest czternasta. + It is two o'clock. - Jest druga. + January - styczeń + July - lipiec + June - czerwiec + Keep the change. - Reszta dla ciebie. + later - później + left - lewo + many - wiele + March - marzec + May - maj + May we have an extra bed? - Czy możemy prosić dodatkowe łóżko? + midnight - północ + Monday - poniedziałek + much - dużo + My name is... - Mam na imię... + nights - noce + nine - dziewięć + nine hundred - dziewięćset + nine thousand - dziewięć tysięcy + nineteen - dziewiętnaście + ninety - dziewięćdziesiąt + ninth - dziewiąty + No. - Nie. + noon - południe + November - listopad + now - teraz + October - październik + Of course. - Oczywiście. + Okay. - Dobrze. + on the corner - na rogu + once - raz + one - jeden + one hundred - sto + one thousand - tysiąc + platform - peron + Please call me a taxi. - Proszę wezwać mi taksówkę. + Please speak more slowly. - Proszę, mów wolniej. + Please tell me when to get off. - Proszę mi powiedzieć gdzie mam wysiąść. + Please. - Proszę. + private bath - prywata łazienka + Repeat, please. - Powtórz proszę. + right - prawo + roll of toilet paper - rolka papieru toaletowego + room - pokój + Saturday - sobota + second - drugi + September - wrzesień + seven - siedem + seven hundred - siedemset + seven thousand - siedem tysięcy + seventeen - siedemnaście + seventh - siódmy + seventy - siedemdziesiąt + six - sześć + six hundred - sześćset + six thousand - sześć tysięcy + sixteen - szesnaście + sixth - szósty + sixty - sześćdziesiąt + some - trochę + soon - wkrótce + spring - wiosna + Stop! - Stop! + straight ahead - prosto + subway station - stacja metra + summer - lato + Sunday - niedziela + supper - kolacja + ten - dziesięć + ten percent - dziesięć procent + ten thousand - dziesięć tysięcy + tenth - dziesiąty + Thank you very much. - Bardzo dziękuję. + Thank you. - Dziękuję. + That's right. - Zgadza się. + The bill, please. - Proszę o rachunek. + third - trzeci + thirteen - trzynaście + thirty - trzydzieści + three - trzy + three hundred - trzysta + three thousand - trzy tysiące + Thursday - czwartek + today - dzisiaj + tomorrow - jutro + track - tor + train station - stacja kolejowa + tram station - przystanek tramwajowy + traveller's checks - czeki podróżne + Tuesday - wtorek + twelve - dwanaście + twenty - dwadzieścia + twenty-one - dwadzieścia jeden + twice - dwukrotnie + two - dwa + two hundred - dwieście + two thousand - dwa tysiące + Watch out! - Uważaj! + Wednesday - środa + What is your name? - Jak masz na imię? + What time is it? - Która godzina? + What town is this? - Co to za miasto? + What? - Co? + When does it arrive? - Kiedy przyjeżdża? + When does it leave? - Kiedy odjeżdża? + When? - Kiedy? + Where is the nearest bank? - Gdzie jest najbliższy bank? + Where is the nearest... - Gdzie jest najbliższa... + Where is... ? - Gdzie jest... ? + Where? - Gdzie? + Which line goes to...? - Jaka linia kursuje do...? + Whitestork - Bocian + Who? - Kto? + Why? - Dlaczego? + winter - zima + Yes. - Tak. + yesterday - wczoraj + You are welcome. - Proszę. + zero - zero + \ No newline at end of file diff --git a/debian/whitestorkplugins/usr/share/doc/whitestorkplugins/changelog.Debian.gz b/debian/whitestorkplugins/usr/share/doc/whitestorkplugins/changelog.Debian.gz new file mode 100644 index 0000000000000000000000000000000000000000..3db3bb9f92e444ca6245957cd043d0d334494df4 GIT binary patch literal 406 zcmV;H0crjpiwFq*0H#I)17m1mZf9j|Z)YwY@lhkV|4X`*Fb0*hDe;(8IgBsw-92 z?;&$cxOMaya_ETl;j8mwQ2?C7;BsdfS|7mpJpm4bqXcL7oG7qV8^WN?8I%y`3PioX zvpQMN7!I?EHpm^ptsf4-b|%3>sZSzI{^YEbX*D_M=i_9cwT@@5Rb{X)kcu8KaI`g8E1{JILk)Hj3fKv35)OPMxp`$0Iw*? A6aWAK literal 0 HcmV?d00001 diff --git a/debian/whitestorkplugins/usr/share/doc/whitestorkplugins/copyright b/debian/whitestorkplugins/usr/share/doc/whitestorkplugins/copyright new file mode 100644 index 0000000..83db946 --- /dev/null +++ b/debian/whitestorkplugins/usr/share/doc/whitestorkplugins/copyright @@ -0,0 +1,15 @@ +This package was debianized by Krzysztof Sasiak on +Thu, 29 Mar 2007 13:28:58 +0200. + +It was downloaded from https://garage.maemo.org + +Upstream Author: WhiteStork development team + +Copyright: Comarch 2006-2007 + +License: + +All components are either under the GPL or LGPL. The complete text of the GPL and LGPL licenses can be found in the /usr/share/common-licenses/GPL and /usr/share/common-licenses/LGPL files. + +The Debian packaging is (C) 2007, Krzysiek Sasiak and +is licensed under the GPL, see `/usr/share/common-licenses/GPL'. diff --git a/debian/whitestorkplugins/usr/share/pixmaps/engine_xdxf_icon.png b/debian/whitestorkplugins/usr/share/pixmaps/engine_xdxf_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b35c0ccbc297274d74a7fd88bf6ab6906905e798 GIT binary patch literal 944 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4m>B|mLR|m<|G!|t0tN;Lp!g^l zLLqQkrT~b5kqL40X_*&C4gsTB+XczhDN3XE)M-9L@rd$YKTt zZXpn6ymYtj4^Yt4)5S5Q;#R6ZCm(|W%jJLnFBbb%lgWWfTi38x zhc}t5JrpL>Z=L$4acx4SM^(am!N2=Y=V!X|L{|4?AAZbOy^-O?ma>?7kh?rx{an^L HB{Ts5te|Jm literal 0 HcmV?d00001 diff --git a/generate_locale b/generate_locale new file mode 100755 index 0000000..5d7d51e --- /dev/null +++ b/generate_locale @@ -0,0 +1,9 @@ +#!/bin/bash + +echo -e -n "Generating locale...\n" +for nazwa in `find $1 -name *.po -type f -printf "%f\n"` + do + tekst=${nazwa%.po} + install -d $2/$tekst/LC_MESSAGES/ + msgfmt $1/$nazwa -o $2/$tekst/LC_MESSAGES/whitestork.mo + done diff --git a/generate_repo b/generate_repo new file mode 100755 index 0000000..bdf5a3b --- /dev/null +++ b/generate_repo @@ -0,0 +1,12 @@ +#!/bin/sh + +test=`arch | tr -d [:space:]` +case $test in + i686) ARCH=i386;; + arm) ARCH=armel;; +esac + +echo $ARCH +install -d $1/dists/mistral/free/binary-$ARCH +cp *.deb $1/dists/mistral/free/binary-$ARCH +cd $1 && dpkg-scanpackages dists/mistral/free/binary-$ARCH /dev/null | gzip -9c > dists/mistral/free/binary-$ARCH/Packages.gz diff --git a/include/dictionary_engine.h b/include/dictionary_engine.h new file mode 100644 index 0000000..20ada28 --- /dev/null +++ b/include/dictionary_engine.h @@ -0,0 +1,296 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#ifndef _DICTIONARY_ENGINE_BASE +#define _DICTIONARY_ENGINE_BASE + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef NOLOGS + #include + #define eg_debug g_debug + #define eg_warning g_warning + #define eg_error g_error + #define eg_critical g_critical +#else + #define eg_debug(frm,...) while(FALSE) + #define eg_warning(frm,...) while(FALSE) + #define eg_error(frm,...) while(FALSE) + #define eg_critical(frm,...) while(FALSE) +#endif + +#define eg_malloc(n) g_try_malloc0(n) +#define eg_free(n) g_free(n); n = NULL + +//______________________________________________________________________________ +// ***************************************************************************** +//************************************************************* HEADERS SECTION: +//------------------------------------------------------------------------------ +// header with gnu library for C - most of types and functions needed it (all +// started from g* and g_*(). +#include +//------------------------------------------------------------------------------ + +#define _GLOBAL_FUNCTIONS_NAME_ "engine_global_functions" +#define _GLOBAL_FUNCTIONS_ engine_global_functions + +//______________________________________________________________________________ +// ***************************************************************************** +//******************************************************* GLOBAL MACROS SECTION: +//------------------------------------------------------------------------------ +#define dict_eng_module_check(module,location) \ + ( (module).engine_check( (location) ) ) +//------------------------------------------------------------------------------ +#define dict_eng_module_get_description(module) \ + ( (module).engine_description() ) +//------------------------------------------------------------------------------ +#define dict_eng_module_get_version(module) \ + ( (module).engine_version() ) +//------------------------------------------------------------------------------ +#define dict_eng_module_get_format(module) \ + ( (module).engine_version() ) +//------------------------------------------------------------------------------ +#define dict_eng_module_create(module,location,flags) \ + ( (module).engine_create( (location), (flags), NULL, NULL, 0.01 ) ) +//------------------------------------------------------------------------------ +#define dict_eng_module_create_ext(module, \ + location, \ + flags, \ + progress_handler, \ + progress_data, \ + seed \ + ) ( \ + (module).engine_create( (location), \ + (flags), \ + (progress_handler), \ + (progress_data), \ + (seed) \ + )) +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//****************************************** CONCRETE DICTIONARY MACROS SECTION: +//------------------------------------------------------------------------------ +#define dict_eng_set_progress_seed(engine, signal, val) ( \ + (engine) -> engine_set_progress_seed( (engine), \ + (signal), \ + (val) \ + )) +//------------------------------------------------------------------------------ +#define dict_eng_set_auto_free(engine, state) \ + (engine) -> engine_set_auto_free( (engine), (state) ) +//------------------------------------------------------------------------------ +#define dict_eng_optimize(engine) \ + ((engine) -> engine_optimize( (engine) )) +//------------------------------------------------------------------------------ +#define dict_eng_is_optimized( engine ) \ + ((engine) -> engine_is_optimized( (engine) )) +//------------------------------------------------------------------------------ +#define dict_eng_get_location(engine) \ + ((engine) -> engine_location( (engine) )) +//------------------------------------------------------------------------------ +#define dict_eng_get_last_status(engine) \ + ((engine) -> engine_error( (engine) )) +//------------------------------------------------------------------------------ +#define dict_eng_status_message(engine, error) \ + ((engine) -> engine_error_message( (error) )) +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +#define dict_eng_destroy(engine) \ + ((engine) -> engine_close( (engine) )) +//------------------------------------------------------------------------------ +#define dict_eng_search_word_list(engine,pattern,data) \ + ((engine) -> engine_search_word_list( (engine), \ + (pattern), \ + (data) \ + )) +//------------------------------------------------------------------------------ +#define dict_eng_search_word_translation(engine,word,data) \ + ((engine) -> engine_search_word_translation( (engine), \ + (word), \ + (data) \ + )) +//------------------------------------------------------------------------------ +#define dict_eng_search_word_translation_extended(engine,word) \ + ((engine) -> engine_search_word_translation_extended((engine), \ + (pattern) \ + )) +//------------------------------------------------------------------------------ +#define dict_eng_set_callback(engine,signal,c_handler,data) \ + ((engine) -> engine_set_callback( (engine), \ + (signal), \ + (c_handler), \ + (data) \ + )) +//------------------------------------------------------------------------------ +#define dict_eng_add_word(engine,word,tran) \ + ((engine) -> engine_add_word( (engine), \ + (word), \ + (tran) \ + )) +//------------------------------------------------------------------------------ +#define dict_eng_remove_word(engine,word) \ + ((engine) -> engine_remove_word( (engine), \ + (word) \ + )) +//------------------------------------------------------------------------------ +#define dict_eng_get_lang_from(engine) \ + ((engine) -> engine_get_lang_from( (engine) )) +//------------------------------------------------------------------------------ +#define dict_eng_get_lang_to(engine) \ + ((engine) -> engine_get_lang_to( (engine) )) +//------------------------------------------------------------------------------ +#define dict_eng_get_title(engine) \ + ((engine) -> engine_get_title( (engine) )) +//------------------------------------------------------------------------------ +#define dict_eng_get_icon_path(engine) \ + ((engine) -> engine_get_icon_path( (engine) )) +//------------------------------------------------------------------------------ + + + +//______________________________________________________________________________ +// ***************************************************************************** +//************************************ SIGNALS DEFINITION FOR CALLBACKS SECTION: +//------------------------------------------------------------------------------ +#define ENGINE_WORD_LIST_SIGNAL "on_word_list_found" +//------------------------------------------------------------------------------ +#define ENGINE_WORD_TRANSLATION_SIGNAL "on_word_translation_found" +//------------------------------------------------------------------------------ +#define ENGINE_PROGRESS_OPTIMIZING_SIGNAL "on_progress_optimizing" +//------------------------------------------------------------------------------ + +//______________________________________________________________________________ +// ***************************************************************************** +//************************************************** DEFINITIONS OF ENUMS TYPES: +//------------------------------------------------------------------------------ +typedef enum +{ + ENGINE_CREATE = 0, + ENGINE_NO, + ENGINE_REFRESH +} EngineOptimizationFlag; +//------------------------------------------------------------------------------ +typedef enum +{ + ENGINE_NO_ERROR = 0, + ENGINE_WRONG_FILE, + ENGINE_COULDNT_READ, + ENGINE_COULDNT_WRITE, + ENGINE_INTERNAL_ERROR, + ENGINE_NO_FILE, + ENGINE_OUT_OF_MEMORY +} +EngineStatus; +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//********************************************* DEFINITIONS OF CALLBACK'S TYPES: +//------------------------------------------------------------------------------ +typedef void (*cb_word_list)(GArray* list, + gchar* pattern, + gpointer user_data, + EngineStatus error); +//------------------------------------------------------------------------------ +typedef void (*cb_word_translation)(gchar* translation, + gchar* word, + gpointer user_data, + EngineStatus error); +//------------------------------------------------------------------------------ +typedef void (*cb_progress)(gdouble value, + gpointer user_data, + EngineStatus error); +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +struct _Engine; +typedef struct _Engine Engine; + +struct _Engine +{ + // 0.1 API specification + void (*engine_set_auto_free)(Engine* engine, + gboolean state); + gchar* (*engine_location)(Engine* engine); + gboolean (*engine_is_optimized)(Engine* engine); + void (*engine_optimize)(Engine* engine); + void (*engine_search_word_list)(Engine* engine, + gchar* pattern, + gpointer data); + void (*engine_search_word_translation)(Engine* engine, + gchar* word, + gpointer data); + void (*engine_close)(Engine* engine); + // engine status + EngineStatus (*engine_status)(Engine* engine); + gchar* (*engine_error_message)(EngineStatus error); + // callbacks + gpointer (*engine_set_callback)(Engine* engine, + gchar* signal, + gpointer c_handler, + gpointer user_data); + void (*engine_set_progress_seed)(Engine* engine, + gchar* signal, + gdouble seed); + // 0.2 API specification's functions + gboolean (*engine_add_word)(Engine* engine, + gchar* word, + gchar* translation); + gboolean (*engine_remove_word)(Engine* engine, + gchar* word); + gchar* (*engine_get_lang_from)(Engine* engine); + gchar* (*engine_get_lang_to)(Engine* engine); + gchar* (*engine_get_title)(Engine* engine); + gchar* (*engine_get_icon_path)(Engine* engine); + + // dictionary independent data + gpointer engine_data; +}; +//------------------------------------------------------------------------------ +typedef struct { + gboolean (*engine_check)(gchar* location); + gchar* (*engine_description)(void); + gchar* (*engine_format)(void); + gchar* (*engine_version)(void); + Engine* (*engine_create)(gchar* location, + EngineOptimizationFlag flags, + cb_progress progress_handler, + gpointer progress_data, + gdouble seed); +} +EngineModule; +//------------------------------------------------------------------------------ +typedef EngineModule (*getting_additional)(void); +//------------------------------------------------------------------------------ +extern EngineModule engine_global_functions(void); +//------------------------------------------------------------------------------ + + +#ifdef __cplusplus +} +#endif +#endif /* _DICTIONARY_ENGINE_BASE */ diff --git a/include/ws_dbus.h b/include/ws_dbus.h new file mode 100644 index 0000000..82d954d --- /dev/null +++ b/include/ws_dbus.h @@ -0,0 +1,275 @@ +/* +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Copyright 2006 ComArch S.A. +*/ + +#ifndef _WS_DBUS +#define _WS_DBUS + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include + +/**\brief Callback function definition +* +*@param error - pointer to a GError structure. Currently not used +*@param words - GArray of osso_rpc_t structures containing sent data +*@param user_data - data passed by user while setting the callback +function with ::ws_dbus_set_cb +*\sa ws_dbus_set_cb +*/ +typedef void (* ws_dbus_cb) (GError *error, gpointer data, gpointer user_data); + +/**\brief This structure contains data vital for DBUS communication. +* +* These are for example both the local and remote addresses of the applications +which are supposed to communicate. In this case they are the GUI and the +MANAGER +* The fields shouldn't be modified directly. It should be done by ws_dbus_config + function +*\sa ws_dbus_config +*/ + +typedef enum +{ + WS_DBUS_TYPE_STRING = DBUS_TYPE_STRING, + WS_DBUS_TYPE_INT = DBUS_TYPE_INT32, + WS_DBUS_TYPE_UINT = DBUS_TYPE_UINT32, + WS_DBUS_TYPE_BOOLEAN = DBUS_TYPE_BOOLEAN, + WS_DBUS_TYPE_DOUBLE = DBUS_TYPE_DOUBLE, + WS_DBUS_TYPE_INVALID = DBUS_TYPE_INVALID, + WS_DBUS_TYPE_GARRAY = ((int) 'a'), + WS_DBUS_TYPE_SIGNAL = DBUS_TYPE_INT32 +} WSDBusDataType; + +struct _WSDBusData +{ + osso_context_t * context; ///ws_dbus_create and after setting all D-BUS + parameters with the ws_dbus_config function. +*The structure it returns is necessary to call out every function implemented in + this wrapper library. +*@param ws_dbus_data - it's a structure containing the unique paths to objects +and interfaces to be registered in the DBus session daemon +*@return WS_STATUS_OK - on success \n +*WS_STATUS_ERROR - on error +*\sa ::WSDBusConfig, ws_dbus_create, ws_dbus_config +*/ +WSDBusStatus ws_dbus_connect (WSDBusData * ws_dbus_data); + +/**\brief Function deinitializing D-BUS wrapper library +* +*Before the program exits, all memory allocated by D-BUS should be freed. +@param ws_dbus_data - pointer to a structure uniquely identifying the +application for DBus +*@return WS_STATUS_OK - on success \n +*WS_STATUS_ERROR - on error +*/ + +void ws_dbus_destroy (WSDBusData * ws_dbus_data); + +/**\brief This function is used for setting a callback function for some predefined signals. +* +*Some of the signals should be used only by the GUI, others by the +MANAGER. +* +*@param ws_dbus_data - pointer to a structure uniquely identifying the +application for D-BUS +*@param detailed_signal - string containing the signal name which will trigger +the function passed in +*the c_func parameter. +*@param c_func - is a pointer to the signal handling function. +*@param user_data - is the data passed directly to the signal handling function +* +*The predefined signal values for the GUI part are: +* +* - "return_words" - used for receiving a list of words found by +the MANAGER +* - "return_translations" - used for receiving a list of +translations found by the MANAGER +* - "signal" - used for handling signals from the MANAGER. +In this case they are mainly error signals. +* +*The predefined signal values for the MANAGER part are: +* +* - "find_word" - used for receiving the word a user is looking for +* - "find_translation" - used for receiving the word a user needs +to translate +* - "signal" - used for handling signals from the GUI. +In this case they are termination and stop search signals. +* +*@return WS_STATUS_OK - on success \n +*WS_STATUS_ERROR - on error +*\sa ::WSDBusConfig \n +*#ws_dbus_cb +*/ + +WSDBusStatus ws_dbus_set_cb (WSDBusData * ws_dbus_data, + gchar * detailed_signal, + gpointer c_func, + gpointer user_data); + +WSDBusStatus ws_dbus_add_method (WSDBusData * ws_dbus_data, gchar *method, ...); + + +WSDBusStatus ws_dbus_call_method (WSDBusData * ws_dbus_data, gchar *method, + ...); + +void ws_dbus_multipleargs_test (WSDBusData * ws_dbus_data, gchar *method, ...); + +#define ws_dbus_notify(structure,arg) ws_dbus_call_method(structure,"signal",WS_DBUS_TYPE_SIGNAL,arg,WS_DBUS_TYPE_INVALID) + +#define ws_dbus_client_find_word(structure,arg) ws_dbus_call_method(structure,"find_word",WS_DBUS_TYPE_STRING,arg,WS_DBUS_TYPE_INVALID) + +#define ws_dbus_client_find_translation(structure,arg) ws_dbus_call_method(structure,"find_translation",WS_DBUS_TYPE_STRING,arg,WS_DBUS_TYPE_INVALID) + +#define ws_dbus_client_add_bookmark(structure,arg1,arg2) ws_dbus_call_method(structure,"signal",WS_DBUS_TYPE_STRING,arg1,WS_DBUS_TYPE_STRING,arg2,WS_DBUS_TYPE_INVALID) + +#define ws_dbus_client_remove_bookmark(structure,arg) ws_dbus_call_method(structure,"remove_bookmark",WS_DBUS_TYPE_STRING,arg,WS_DBUS_TYPE_INVALID) + +#define ws_dbus_client_extract_dictionary(structure,arg) ws_dbus_call_method(structure,"extract_dictionary",WS_DBUS_TYPE_STRING,arg,WS_DBUS_TYPE_INVALID) + +#define ws_dbus_server_return_extracted_dict(structure,arg) ws_dbus_call_method(structure,"return_extracted_dict",WS_DBUS_TYPE_STRING,arg,WS_DBUS_TYPE_INVALID) + +#define ws_dbus_server_return_words(structure,arg) ws_dbus_call_method(structure,"return_words",WS_DBUS_TYPE_GARRAY,arg,WS_DBUS_TYPE_INVALID) + +#define ws_dbus_server_return_translations(structure,arg) ws_dbus_call_method(structure,"return_translations",WS_DBUS_TYPE_STRING,arg,WS_DBUS_TYPE_INVALID) + +#define ws_dbus_server_update_progressbar(structure,arg) ws_dbus_call_method(structure,"update_progressbar",WS_DBUS_TYPE_DOUBLE,arg,WS_DBUS_TYPE_INVALID) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/logs/clean.log b/logs/clean.log new file mode 100644 index 0000000..d64bdd5 --- /dev/null +++ b/logs/clean.log @@ -0,0 +1,33 @@ +make[1]: Entering directory `/home/str/development/mdictionary/trunk/src/gui' +rm -f bin/* +done +make[1]: Leaving directory `/home/str/development/mdictionary/trunk/src/gui' +make[1]: Entering directory `/home/str/development/mdictionary/trunk/src/dbus_wrapper' +rm -rf bin/* +rm -rf doc/* +make[1]: Leaving directory `/home/str/development/mdictionary/trunk/src/dbus_wrapper' +make[1]: Entering directory `/home/str/development/mdictionary/trunk/src/plugins/xdxf' +make[1]: Leaving directory `/home/str/development/mdictionary/trunk/src/plugins/xdxf' +make[1]: Entering directory `/home/str/development/mdictionary/trunk/src/plugins/stardict' +Project 'StarDictEngine' directories has been cleaned. +make[1]: Leaving directory `/home/str/development/mdictionary/trunk/src/plugins/stardict' +make[1]: Entering directory `/home/str/development/mdictionary/trunk/src/manager' +rm -f ./src/*.o ./bin/WhiteStorkManager ./src/*~ ./*~ +rm -f ./include/*~ +make[1]: Leaving directory `/home/str/development/mdictionary/trunk/src/manager' +make[1]: Entering directory `/home/str/development/mdictionary/trunk/src/manager' +rm -f ./src/*.o ./bin/WhiteStorkManager ./src/*~ ./*~ +rm -f ./include/*~ +make[1]: Leaving directory `/home/str/development/mdictionary/trunk/src/manager' +make[1]: Entering directory `/home/str/development/mdictionary/trunk/src/bookmarks/sql' +Project's 'BookmarkEngine' directories has been cleaned. +make[1]: Leaving directory `/home/str/development/mdictionary/trunk/src/bookmarks/sql' +make[1]: Entering directory `/home/str/development/mdictionary/trunk/src/bookmarks/sql3' +Project's 'BookmarkEngine' directories has been cleaned. +make[1]: Leaving directory `/home/str/development/mdictionary/trunk/src/bookmarks/sql3' +make[1]: Entering directory `/home/str/development/mdictionary/trunk/src/bookmarks/bdb' +Project 'BookmarkEngine' directories has been cleaned. +make[1]: Leaving directory `/home/str/development/mdictionary/trunk/src/bookmarks/bdb' +make[1]: Entering directory `/home/str/development/mdictionary/trunk/src/bookmarks/xdxf' +Project's 'BookmarkEngine' directories has been cleaned. +make[1]: Leaving directory `/home/str/development/mdictionary/trunk/src/bookmarks/xdxf' diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000..08090ce --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,5 @@ +# List of source files containing translatable strings. + +# Package source files +../gui/src/ws_gui_layout.c +../gui/src/ws_gui_callbacks.c \ No newline at end of file diff --git a/po/domain.mo b/po/domain.mo new file mode 100644 index 0000000000000000000000000000000000000000..dd44feedf4005829606b9de7c48e30250ac8f49c GIT binary patch literal 2141 zcmZvc%ZnUE9LFmrYBD|&W7KFgRt!oo_GYub;Dt+v>8Wa} zy0`7VDc;13;6=oXcu^2!!IO9sJopa?qToR!2SI`t@!SS^{e^i z=z)(I#%ataF<;up*g3Fq7akY~_cL}kcnCZQ9xmkL;KPtlf(O6_@P6=BkoMJz^=82i zcnIt3-~*rl?*R>XAGi%32Hyqm1wSn0kHM!Pe*r!Y{s2-uzk%fc5AZSYUy$q_Log-q z1W4=8ffV0GJe~!sg{;6u$Qo>cUxJT-|A6HG2%JzJ$3e1t3Z#;p0n4b-S&-u1#K#9g z3zGZ}cm(_a#E*T72if@?r2M`r*1s$GeX;%{_z=GTT&({IlD)q{vbPUGk)5L;`8xqV z0X`2>UFsl0VsC+T4iY4L7K91*9!PfH2akcDfJl{n4L$>Y1Cstv;A!wz@C>*gPN~i> zfaL!&9(0aNAldDLRF@uzvgAIgjz=-cF8LzAG)V6hCdE&K@*^8GCpnjt9C??t7}w^;%M@mo10^m zft8X~w~TR;`>G!)qlHz{v8oAER@=Q&Q%>aD>%NNERi*v>!L@vQBJ$A6ZDnGYua`Ny z8V3P)eYnumHCEZ) zSUF{~EL+U*Cc19*-D_hb^E-Ch{Zs9D^iThyisXgTcwZ}8;#3>nlpBA zvD92@)@MnbpPMgLjgF*-k2FNE5jy!?7zm|b=lv~Vos8a4&UhCty!@KCFxyN4ZA$Ca zb>H|(56b+)hKfq8jT>MFR*aS0{Z8%K8wfuWWA4;Vww`V%X*2G2Orq6Du^T2-@sM?= za!W~`?NX@wX@4kKPm7`dZ2_+7#6yj<%$Ip+LYqln!*{W9S?=KC$PvP2t0S8Z^P6`Q zes3kk{e#udgdY!Qv9wH*P9>fh7l|G28(-)Y%@U^3SOhA|6%s?i=NDvs6v!c4b@5+Q z)jh&wQ#Xr8V#s, 2006. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-11-14 11:34+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Anna Gadomska \n" +"Language-Team: polish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../gui/src/ws_gui_layout.c:42 +msgid "ws_ni_welcome" +msgstr "Welcome to mDictionary!" + +#: ../gui/src/ws_gui_layout.c:174 ../gui/src/ws_gui_layout.c:351 +msgid "ws_me_search_find" +msgstr "Find" + +#: ../gui/src/ws_gui_layout.c:266 +msgid "ws_me_dictionaries" +msgstr "Dictionaries" + +#: ../gui/src/ws_gui_layout.c:268 +msgid "ws_me_bookmarks" +msgstr "Bookmarks" + +#: ../gui/src/ws_gui_layout.c:270 +msgid "ws_me_edit" +msgstr "Edit" + +#: ../gui/src/ws_gui_layout.c:272 +msgid "ws_me_view" +msgstr "View" + +#: ../gui/src/ws_gui_layout.c:274 +msgid "ws_me_search" +msgstr "Search" + +#: ../gui/src/ws_gui_layout.c:276 +msgid "ws_me_about" +msgstr "About ..." + +#: ../gui/src/ws_gui_layout.c:278 +msgid "ws_me_close" +msgstr "Close" + +#: ../gui/src/ws_gui_layout.c:285 +msgid "ws_me_dictionaries_load" +msgstr "Load dictionary" + +#: ../gui/src/ws_gui_layout.c:287 +msgid "ws_me_dictionaries_select" +msgstr "Select dictionaries" + +#: ../gui/src/ws_gui_layout.c:289 +msgid "ws_me_dictionaries_remove" +msgstr "Remove dictionaries" + +#: ../gui/src/ws_gui_layout.c:291 +msgid "ws_me_dictionaries_optimize" +msgstr "Optimize dictionaries" + +#: ../gui/src/ws_gui_layout.c:303 +msgid "ws_me_bookmarks_open" +msgstr "Open Bookmarks" + +#: ../gui/src/ws_gui_layout.c:305 +msgid "ws_me_bookmarks_close" +msgstr "Close Bookmarks" + +#: ../gui/src/ws_gui_layout.c:307 +msgid "ws_me_bookmarks_add" +msgstr "Add Bookmark" + +#: ../gui/src/ws_gui_layout.c:309 +msgid "ws_me_bookmarks_remove" +msgstr "Remove Bookmark" + +#: ../gui/src/ws_gui_layout.c:321 +msgid "ws_me_edit_copy" +msgstr "Copy" + +#: ../gui/src/ws_gui_layout.c:323 +msgid "ws_me_edit_paste" +msgstr "Paste" + +#: ../gui/src/ws_gui_layout.c:325 +msgid "ws_me_edit_select_all" +msgstr "Select All" + +#: ../gui/src/ws_gui_layout.c:334 +msgid "ws_me_view_hide_words_list" +msgstr "Hide words list" + +#: ../gui/src/ws_gui_layout.c:336 +msgid "ws_me_view_zoom_in" +msgstr "Zoom in" + +#: ../gui/src/ws_gui_layout.c:338 +msgid "ws_me_view_zoom_out" +msgstr "Zoom out" + +#: ../gui/src/ws_gui_layout.c:340 +msgid "ws_me_view_fullscreen" +msgstr "Full screen" + +#: ../gui/src/ws_gui_layout.c:353 +msgid "ws_me_search_find_next" +msgstr "Find next" + +#: ../gui/src/ws_gui_layout.c:355 +msgid "ws_me_search_find_prev" +msgstr "Find previous" + +#: ../gui/src/ws_gui_layout.c:357 +msgid "ws_me_search_stop" +msgstr "Stop" + +#: ../gui/src/ws_gui_layout.c:560 +msgid "ws_mp_search" +msgstr "Search" + +#: ../gui/src/ws_gui_layout.c:580 +msgid "ws_mp_add_bookmark" +msgstr "Add Bookmark" + +#: ../gui/src/ws_gui_layout.c:580 +msgid "ws_mp_edit_copy" +msgstr "Copy" + +#: ../gui/src/ws_gui_layout.c:585 +msgid "ws_mp_edit_paste" +msgstr "Paste" + +#: ../gui/src/ws_gui_layout.c:590 +msgid "ws_mp_edit_select_all" +msgstr "Select All" + +#: ../gui/src/ws_gui_layout.c:597 +msgid "ws_mp_edit" +msgstr "Edit" + +#: ../gui/src/ws_gui_layout.c:605 +msgid "ws_mp_zoom_in" +msgstr "Zoom in" + +#: ../gui/src/ws_gui_layout.c:610 +msgid "ws_mp_zoom_out" +msgstr "Zoom out" + +#: ../gui/src/ws_gui_layout.c:712 ../gui/src/ws_gui_layout.c:904 +msgid "ws_ti_choose_dictionaries_title" +msgstr "Select dictionaries" + +#: ../gui/src/ws_gui_layout.c:767 ../gui/src/ws_gui_layout.c:941 +#: ../gui/src/ws_gui_layout.c:1233 ../gui/src/ws_gui_layout.c:1427 +#: ../gui/src/ws_gui_layout.c:1488 ../gui/src/ws_gui_layout.c:1432 +msgid "ws_db_cancel" +msgstr "Cancel" + +#: ../gui/src/ws_gui_layout.c:773 ../gui/src/ws_gui_layout.c:946 +#: ../gui/src/ws_gui_layout.c:1422 ../gui/src/ws_gui_layout.c:1483 +#: ../gui/src/ws_gui_layout.c:1427 +msgid "ws_db_ok" +msgstr "OK" + +#: ../gui/src/ws_gui_layout.c:892 +msgid "ws_ni_no_dictionaries_to_optimize" +msgstr "There are no dictionaries to optimize." + +#: ../gui/src/ws_gui_layout.c:1022 +msgid "ws_ti_load_dictionary_title" +msgstr "Load dictionary" + +#: ../gui/src/ws_gui_layout.c:1074 +msgid "ws_ni_dictionaries_activation_question" +msgstr "Would you like to start using this dictionary now?" + +#: ../gui/src/ws_gui_layout.c:1106 +msgid "ws_ni_dictionaries_optimalization_question" +msgstr "Would you like to optimize this dictionary?" + +#: ../gui/src/ws_gui_layout.c:1131 +msgid "ws_ni_dictionary_added" +msgstr "New dictionary has been added." + +#: ../gui/src/ws_gui_layout.c:1138 +msgid "ws_ni_dictionary_wrong_file" +msgstr "Wrong dictionary file." + +#: ../gui/src/ws_gui_layout.c:1189 +msgid "ws_ti_remove_dictionaries_title" +msgstr "Remove dictionaries" + +#: ../gui/src/ws_gui_layout.c:1239 +msgid "ws_bd_remove_dictionaries_remove_selected" +msgstr "remove selected" + +#: ../gui/src/ws_gui_layout.c:1305 +msgid "ws_ti_about_title" +msgstr "About ..." + +#: ../gui/src/ws_gui_layout.c:1339 +msgid "ws_ib_dictionary_removed" +msgstr "Dictionary has been removed" + +#: ../gui/src/ws_gui_layout.c:1401 +msgid "ws_ti_add_bookmark" +msgstr "Add bookmark" + +#: ../gui/src/ws_gui_layout.c:1413 +msgid "ws_ti_bookmarks_add_question" +msgstr "Add to bookmarks?" + +#: ../gui/src/ws_gui_layout.c:1449 +msgid "ws_ni_bookmark_added" +msgstr "Bookmark has been added" + +#: ../gui/src/ws_gui_layout.c:1457 +msgid "ws_ni_bookmark_not_added" +msgstr "Bookmark could not be added" + +#: ../gui/src/ws_gui_layout.c:1462 +msgid "ws_ti_remove_bookmark" +msgstr "Remove bookmark" + +#: ../gui/src/ws_gui_layout.c:1474 +msgid "ws_ni_remove_bookmark_question" +msgstr "Remove from bookmarks?" + +#: ../gui/src/ws_gui_layout.c:1515 +msgid "ws_ni_bookmark_removed" +msgstr "Bookmark has been removed" + +#: ../gui/src/ws_gui_layout.c:1522 +msgid "ws_ni_bookmark_not_removed" +msgstr "Bookmark could not be removed" + +#: ../gui/src/ws_gui_callbacks.c:114 +msgid "ws_ni_error_occured" +msgstr "An error occured" + +#: ../gui/src/ws_gui_callbacks.c:133 +msgid "ws_ni_no_dictionary_available" +msgstr "There is no dictionary available" + +#: ../gui/src/ws_gui_callbacks.c:168 +msgid "ws_pb_caching" +msgstr "Caching ..." + +#: ../gui/src/ws_gui_callbacks.c:212 +msgid "ws_ni_dictionary_unavailable" +msgstr "Dictionary unavailable." + +#: ../gui/src/ws_gui_callbacks.c:289 +#: ../gui/src/ws_gui_layout.c:1534 +msgid "ws_ni_no_words_found" +msgstr "No words found" + +#: ../gui/src/ws_gui_callbacks.c:867 +msgid "ws_ni_no_text_selected" +msgstr "No text selected" + +#: ../gui/src/ws_gui_callbacks.c:970 +msgid "ws_ab_searching" +msgstr "Searching ..." + +#: ../gui/src/ws_gui_callbacks.c:987 +msgid "ws_ni_no_word_typed" +msgstr "No word typed." + +#: ../gui/src/ws_gui_callbacks.c:1008 +msgid "ws_ni_search_aborted" +msgstr "Search has been aborted." + +#: ../gui/src/ws_gui_callbacks.c:1412 +msgid "ws_ni_select_word_to_add" +msgstr "Select word to add." + +#: ../gui/src/ws_gui_callbacks.c:1436 +msgid "ws_ni_select_word_to_remove" +msgstr "Select word to remove." + +#: ../gui/src/ws_gui_callbacks.c:1128 +msgid "ws_ib_max_zoom" +msgstr "Max zoom level reached" + +#: ../gui/src/ws_gui_callbacks.c:1152 +msgid "ws_ib_min_zoom" +msgstr "Min zoom level reached" + +#: ../gui/src/ws_gui_callbacks.c:1161 +msgid "ws_ib_zoom_in" +msgstr "Zooming in" + +#: ../gui/src/ws_gui_callbacks.c:1134 +msgid "ws_ib_zoom_out" +msgstr "Zooming out" + +#: ../gui/src/ws_gui_callbacks.c:1018 +msgid "ws_ib_fullscreen_on" +msgstr "Fullscreen mode on" + +#: ../gui/src/ws_gui_callbacks.c:1029 +msgid "ws_ib_fullscreen_off" +msgstr "Fullscreen mode off" \ No newline at end of file diff --git a/po/pl_PL.po b/po/pl_PL.po new file mode 100644 index 0000000..305a92a --- /dev/null +++ b/po/pl_PL.po @@ -0,0 +1,550 @@ +# Copyright (C) 2006 +# This file is distributed under the same license as the PACKAGE package. +# Anna Gadomska, , 2006. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-11-14 11:34+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Anna Gadomska \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../gui/src/ws_gui_layout.c:42 +msgid "ws_ni_welcome" +msgstr "


Witamy w słowniku
WhiteStork
" + "

" + +#: ../gui/src/ws_gui_layout.c:45 ../gui/src/ws_gui_callbacks.c:143 +#: ../gui/src/ws_gui_callbacks.c:854 ../gui/src/ws_gui_callbacks.c:980 +msgid " " +msgstr "" + +#: ../gui/src/ws_gui_layout.c:63 ../gui/src/ws_gui_layout.c:1318 +msgid "WhiteStork" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:111 ../gui/src/ws_gui_layout.c:1328 +#: ../gui/src/ws_gui_layout.c:1335 +msgid "Tahoma 12" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:116 +msgid "url_requested" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:174 ../gui/src/ws_gui_layout.c:351 +msgid "ws_me_search_find" +msgstr "Znajdz" + +#: ../gui/src/ws_gui_layout.c:212 +msgid "search" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:217 +msgid "toggled" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:222 ../gui/src/ws_gui_layout.c:227 +#: ../gui/src/ws_gui_layout.c:231 +msgid "clicked" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:266 +msgid "ws_me_dictionaries" +msgstr "Slowniki" + +#: ../gui/src/ws_gui_layout.c:268 +msgid "ws_me_bookmarks" +msgstr "Zakładki" + +#: ../gui/src/ws_gui_layout.c:270 +msgid "ws_me_edit" +msgstr "Edycja" + +#: ../gui/src/ws_gui_layout.c:272 +msgid "ws_me_view" +msgstr "Widok" + +#: ../gui/src/ws_gui_layout.c:274 +msgid "ws_me_search" +msgstr "Znajdź" + +#: ../gui/src/ws_gui_layout.c:276 +msgid "ws_me_about" +msgstr "O programie ..." + +#: ../gui/src/ws_gui_layout.c:278 +msgid "ws_me_close" +msgstr "Zamknij" + +#: ../gui/src/ws_gui_layout.c:285 +msgid "ws_me_dictionaries_load" +msgstr "Załaduj słownik" + +#: ../gui/src/ws_gui_layout.c:287 +msgid "ws_me_dictionaries_select" +msgstr "Wybierz słowniki" + +#: ../gui/src/ws_gui_layout.c:289 +msgid "ws_me_dictionaries_remove" +msgstr "Usuń słowniki" + +#: ../gui/src/ws_gui_layout.c:291 +msgid "ws_me_dictionaries_optimize" +msgstr "Optymalizuj słowniki" + +#: ../gui/src/ws_gui_layout.c:303 +msgid "ws_me_bookmarks_open" +msgstr "Otwórz Zakładki" + +#: ../gui/src/ws_gui_layout.c:305 +msgid "ws_me_bookmarks_close" +msgstr "Zamknij Zakładki" + +#: ../gui/src/ws_gui_layout.c:307 +msgid "ws_me_bookmarks_add" +msgstr "Dodaj do Zakładek" + +#: ../gui/src/ws_gui_layout.c:309 +msgid "ws_me_bookmarks_remove" +msgstr "Usuń z Zakładek" + +#: ../gui/src/ws_gui_layout.c:321 +msgid "ws_me_edit_copy" +msgstr "Kopiuj" + +#: ../gui/src/ws_gui_layout.c:323 +msgid "ws_me_edit_paste" +msgstr "Wklej" + +#: ../gui/src/ws_gui_layout.c:325 +msgid "ws_me_edit_select_all" +msgstr "Zaznacz wszystko" + +#: ../gui/src/ws_gui_layout.c:334 +msgid "ws_me_view_hide_words_list" +msgstr "Ukryj listę słów" + +#: ../gui/src/ws_gui_layout.c:336 +msgid "ws_me_view_zoom_in" +msgstr "Powiększ" + +#: ../gui/src/ws_gui_layout.c:338 +msgid "ws_me_view_zoom_out" +msgstr "Pomniejsz" + +#: ../gui/src/ws_gui_layout.c:340 +msgid "ws_me_view_fullscreen" +msgstr "Pełny ekran" + +#: ../gui/src/ws_gui_layout.c:353 +msgid "ws_me_search_find_next" +msgstr "Znajdź następny" + +#: ../gui/src/ws_gui_layout.c:355 +msgid "ws_me_search_find_prev" +msgstr "Znajdź poprzedni" + +#: ../gui/src/ws_gui_layout.c:357 +msgid "ws_me_search_stop" +msgstr "Zatrzymaj" + +#: ../gui/src/ws_gui_layout.c:410 ../gui/src/ws_gui_layout.c:415 +#: ../gui/src/ws_gui_layout.c:420 ../gui/src/ws_gui_layout.c:425 +#: ../gui/src/ws_gui_layout.c:429 ../gui/src/ws_gui_layout.c:434 +#: ../gui/src/ws_gui_layout.c:439 ../gui/src/ws_gui_layout.c:444 +#: ../gui/src/ws_gui_layout.c:449 ../gui/src/ws_gui_layout.c:454 +#: ../gui/src/ws_gui_layout.c:459 ../gui/src/ws_gui_layout.c:464 +#: ../gui/src/ws_gui_layout.c:469 ../gui/src/ws_gui_layout.c:474 +#: ../gui/src/ws_gui_layout.c:479 ../gui/src/ws_gui_layout.c:484 +#: ../gui/src/ws_gui_layout.c:489 ../gui/src/ws_gui_layout.c:494 +#: ../gui/src/ws_gui_layout.c:499 ../gui/src/ws_gui_layout.c:504 +#: ../gui/src/ws_gui_layout.c:509 ../gui/src/ws_gui_layout.c:515 +#: ../gui/src/ws_gui_layout.c:521 ../gui/src/ws_gui_layout.c:621 +#: ../gui/src/ws_gui_layout.c:626 ../gui/src/ws_gui_layout.c:631 +#: ../gui/src/ws_gui_layout.c:636 ../gui/src/ws_gui_layout.c:641 +#: ../gui/src/ws_gui_layout.c:645 +msgid "activate" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:560 +msgid "ws_mp_search" +msgstr "Znajdź" + +#: ../gui/src/ws_gui_layout.c:580 +msgid "ws_mp_edit_copy" +msgstr "Kopiuj" + +#: ../gui/src/ws_gui_layout.c:585 +msgid "ws_mp_edit_paste" +msgstr "Wklej" + +#: ../gui/src/ws_gui_layout.c:590 +msgid "ws_mp_edit_select_all" +msgstr "Zaznacz wszystko" + +#: ../gui/src/ws_gui_layout.c:597 +msgid "ws_mp_edit" +msgstr "Edycja" + +#: ../gui/src/ws_gui_layout.c:605 +msgid "ws_mp_zoom_in" +msgstr "Powiększ" + +#: ../gui/src/ws_gui_layout.c:610 +msgid "ws_mp_zoom_out" +msgstr "Pomniejsz" + +#: ../gui/src/ws_gui_layout.c:708 ../gui/src/ws_gui_layout.c:868 +#: ../gui/src/ws_gui_layout.c:1185 +msgid "" +"\n" +".::GUI::. /apps/WhiteStork/Dictionaries does not exist!!" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:712 ../gui/src/ws_gui_layout.c:904 +msgid "ws_ti_choose_dictionaries_title" +msgstr "Wybierz słowniki" + +#: ../gui/src/ws_gui_layout.c:741 ../gui/src/ws_gui_layout.c:794 +#: ../gui/src/ws_gui_layout.c:811 ../gui/src/ws_gui_layout.c:1065 +msgid "/active" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:767 ../gui/src/ws_gui_layout.c:941 +#: ../gui/src/ws_gui_layout.c:1233 ../gui/src/ws_gui_layout.c:1427 +#: ../gui/src/ws_gui_layout.c:1488 +msgid "ws_db_cancel" +msgstr "Anuluj" + +#: ../gui/src/ws_gui_layout.c:773 ../gui/src/ws_gui_layout.c:946 +#: ../gui/src/ws_gui_layout.c:1422 ../gui/src/ws_gui_layout.c:1483 +msgid "ws_db_ok" +msgstr "OK" + +#: ../gui/src/ws_gui_layout.c:792 ../gui/src/ws_gui_layout.c:809 +#: ../gui/src/ws_gui_layout.c:966 ../gui/src/ws_gui_layout.c:986 +#: ../gui/src/ws_gui_layout.c:1055 ../gui/src/ws_gui_layout.c:1063 +#: ../gui/src/ws_gui_layout.c:1097 ../gui/src/ws_gui_layout.c:1257 +msgid "/" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:876 ../gui/src/ws_gui_layout.c:968 +#: ../gui/src/ws_gui_layout.c:988 ../gui/src/ws_gui_layout.c:1099 +msgid "/optimized" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:892 +msgid "ws_ni_no_dictionaries_to_optimize" +msgstr "Brak słowników do zoptymalizowania." + +#: ../gui/src/ws_gui_layout.c:1022 +msgid "ws_ti_load_dictionary_title" +msgstr "Załaduj słownik" + +#: ../gui/src/ws_gui_layout.c:1051 +msgid ".xdxf" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1055 +msgid "/path" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1074 +msgid "ws_ni_dictionaries_activation_question" +msgstr "Czy chcesz zacząć używać ten słownik już teraz?" + +#: ../gui/src/ws_gui_layout.c:1106 +msgid "ws_ni_dictionaries_optimalization_question" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1131 +msgid "ws_ni_dictionary_added" +msgstr "Nowy słownik został dodany." + +#: ../gui/src/ws_gui_layout.c:1138 +msgid "ws_ni_dictionary_wrong_file" +msgstr "Zły plik słownika." + +#: ../gui/src/ws_gui_layout.c:1189 +msgid "ws_ti_remove_dictionaries_title" +msgstr "Usuń słowniki" + +#: ../gui/src/ws_gui_layout.c:1226 +msgid "bookmarks" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1239 +msgid "ws_bd_remove_dictionaries_remove_selected" +msgstr "usuń zaznaczone" + +#: ../gui/src/ws_gui_layout.c:1305 +msgid "ws_ti_about_title" +msgstr "O Programie ..." + +#: ../gui/src/ws_gui_layout.c:1315 +msgid "/usr/share/pixmaps/whitestork.png" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1319 +msgid "Tahoma 18" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1321 +msgid "__________" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1324 +msgid "" +"Maemo Multilingual Dictionary\n" +"ver. " +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1333 +msgid "" +"Copyright 2006, ComArch S.A\n" +"All rightsreserved" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1355 +msgid "Tahoma 10" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1363 +msgid "" +"The following third party\n" +"components may be\n" +"included depending \n" +"on your system configuration:\n" +"\n" +"D-BUS - License information:\n" +"http://opensource.org/licenses/academic.php" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1401 +msgid "ws_ti_add_bookmark" +msgstr "Dodaj do zakładek" + +#: ../gui/src/ws_gui_layout.c:1413 +msgid "ws_ti_bookmarks_add_question" +msgstr "Dodać do zakładek?" + +#: ../gui/src/ws_gui_layout.c:1437 +msgid "" +"\n" +".::GUI::. Bookmark added, happy days! :D\n" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1444 +msgid "" +"\n" +".::GUI::. Sorry ;-(" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1449 +msgid "ws_ni_bookmark_added" +msgstr "Zakładka została dodana" + +#: ../gui/src/ws_gui_layout.c:1457 +msgid "ws_ni_bookmark_not_added" +msgstr "Zakładka nie mogła być dodana" + + +#: ../gui/src/ws_gui_layout.c:1462 +msgid "ws_ti_remove_bookmark" +msgstr "Usuń zakładkę" + +#: ../gui/src/ws_gui_layout.c:1474 +msgid "ws_ni_remove_bookmark_question" +msgstr "Usunąć z zakładek?" + +#: ../gui/src/ws_gui_layout.c:1498 +msgid "" +"\n" +".::GUI::. Bookmark removed, well done! :D\n" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1504 +msgid "" +"\n" +".::GUI::. Sorry\n" +msgstr "" + + +#: ../gui/src/ws_gui_layout.c:1515 +msgid "ws_ni_bookmark_removed" +msgstr "Zakładkę usunieto." + +#: ../gui/src/ws_gui_layout.c:1522 +msgid "ws_ni_bookmark_not_removed" +msgstr "Zakładka nie mogła zostać usunięta" + +#: ../gui/src/ws_gui_callbacks.c:44 +#, c-format +msgid "XDXF->%s() start counting time for function '%s()'.\n" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:74 +#, c-format +msgid "XDXF->%s() function '%s()' was working for: %g [s] or %ld [us].\n" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:114 +msgid "ws_ni_error_occured" +msgstr "Wystąpił błąd." + +#: ../gui/src/ws_gui_callbacks.c:119 +msgid "response" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:133 +msgid "ws_ni_no_dictionary_available" +msgstr "Brak dostępnych słowników." + +#: ../gui/src/ws_gui_callbacks.c:168 +msgid "ws_pb_caching" +msgstr "Optymalizacja ..." + +#: ../gui/src/ws_gui_callbacks.c:212 +msgid "ws_ni_dictionary_unavailable" +msgstr "Słownik niedostępny." + +#: ../gui/src/ws_gui_callbacks.c:289 +msgid "ws_ni_no_words_found" +msgstr "Nie znaleziono słów." + +#: ../gui/src/ws_gui_callbacks.c:758 +msgid "Name" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:760 +msgid "text" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:857 ../gui/src/ws_gui_callbacks.c:909 +#: ../gui/src/ws_gui_callbacks.c:915 ../gui/src/ws_gui_callbacks.c:960 +msgid "prefix" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:867 +msgid "ws_ni_no_text_selected" +msgstr "Zaznacz tekst." + +#: ../gui/src/ws_gui_callbacks.c:913 +msgid "\n" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:970 +msgid "ws_ab_searching" +msgstr "Wyszukiwanie ..." + +#: ../gui/src/ws_gui_callbacks.c:987 +msgid "ws_ni_no_word_typed" +msgstr "Nie wpisano słowa." + +#: ../gui/src/ws_gui_callbacks.c:1008 +msgid "ws_ni_search_aborted" +msgstr "Wyszukiwanie zostało przerwane." + +#: ../gui/src/ws_gui_callbacks.c:1112 +msgid "file:" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1160 +msgid "button-press-event" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1268 ../gui/src/ws_gui_callbacks.c:1270 +#: ../gui/src/ws_gui_callbacks.c:1283 +msgid "" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1277 +msgid "" +"
" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1289 ../gui/src/ws_gui_callbacks.c:1291 +#: ../gui/src/ws_gui_callbacks.c:1299 +msgid "" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1297 +msgid "
" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1305 ../gui/src/ws_gui_callbacks.c:1307 +#: ../gui/src/ws_gui_callbacks.c:1316 +msgid "" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1313 +msgid "" +"
" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1322 ../gui/src/ws_gui_callbacks.c:1324 +#: ../gui/src/ws_gui_callbacks.c:1332 +msgid "" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1330 +msgid "

" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1339 +msgid "
" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1341 +#, c-format +msgid ".::GUI::. Zawartosc stringa to: \"%s\"" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1345 +#, c-format +msgid ".::GUI::. Zawartosc RAW to: \"%s\"" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1362 ../gui/src/ws_gui_callbacks.c:1384 +msgid "/bookmarks" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1362 ../gui/src/ws_gui_callbacks.c:1384 +msgid "active" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1366 +msgid "" +"\n" +".::GUI::. Bookmark mode on\n" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1388 +msgid "" +"\n" +".::GUI::. Bookmark mode off\n" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1402 ../gui/src/ws_gui_callbacks.c:1426 +#, c-format +msgid ".::GUI::. LAST_WORD: \"%s\"" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1412 +msgid "ws_ni_select_word_to_add" +msgstr "Wybierz słowo do dodania." + +#: ../gui/src/ws_gui_callbacks.c:1436 +msgid "ws_ni_select_word_to_remove" +msgstr "Wybierz słowo do usunięcia." diff --git a/po/pl_Pl.po b/po/pl_Pl.po new file mode 100644 index 0000000..e937d8f --- /dev/null +++ b/po/pl_Pl.po @@ -0,0 +1,288 @@ +# 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. +# + +msgid "" +msgstr "" +"Project-Id-Version: 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-10-20 12:32+0200\n" +"PO-Revision-Date: 2006-10-21 12:50+0200\n" +"Last-Translator: Ania Gadomska \n" +"Language-Team: polish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../gui/src/ws_gui_layout.c:57 ../gui/src/ws_gui_layout.c:1225 +msgid "WhiteStork" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:105 ../gui/src/ws_gui_layout.c:1232 +#: ../gui/src/ws_gui_layout.c:1238 +msgid "Tahoma 12" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:109 +msgid "url_requested" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:159 +msgid "Find: " +msgstr "Znajdź" + +#: ../gui/src/ws_gui_layout.c:249 +msgid "Dictionaries" +msgstr "Słowniki" + +#: ../gui/src/ws_gui_layout.c:251 ../gui/src/ws_gui_layout.c:529 +msgid "Edit" +msgstr "Edycja" + +#: ../gui/src/ws_gui_layout.c:253 +msgid "View" +msgstr "Widok" + +#: ../gui/src/ws_gui_layout.c:255 ../gui/src/ws_gui_layout.c:492 +msgid "Search" +msgstr "Szukaj" + +#: ../gui/src/ws_gui_layout.c:257 +msgid "About..." +msgstr "O programie..." + +#: ../gui/src/ws_gui_layout.c:259 +msgid "Close" +msgstr "Zamknij" + +#: ../gui/src/ws_gui_layout.c:266 ../gui/src/ws_gui_layout.c:938 +msgid "Load dictionary" +msgstr "Ładuj słowniki" + +#: ../gui/src/ws_gui_layout.c:268 +msgid "Select dictionaries ..." +msgstr "Wybierz sowniki ..." + +#: ../gui/src/ws_gui_layout.c:270 +msgid "Remove dictionaries ..." +msgstr "Usuń słowniki ..." + +#: ../gui/src/ws_gui_layout.c:272 +msgid "Optimize dictionaries ..." +msgstr "Zopytmalizuj słwoniki ..." + +#: ../gui/src/ws_gui_layout.c:288 ../gui/src/ws_gui_layout.c:512 +msgid "Copy" +msgstr "Kopiuj" + +#: ../gui/src/ws_gui_layout.c:290 ../gui/src/ws_gui_layout.c:517 +msgid "Paste" +msgstr "Wklej" + +#: ../gui/src/ws_gui_layout.c:292 ../gui/src/ws_gui_layout.c:522 +msgid "Select All" +msgstr "Zaznacz wszystko" + +#: ../gui/src/ws_gui_layout.c:301 +msgid "Hide words list" +msgstr "Ukryj liste" + +#: ../gui/src/ws_gui_layout.c:303 ../gui/src/ws_gui_layout.c:537 +msgid "Zoom in" +msgstr "Powiększ" + +#: ../gui/src/ws_gui_layout.c:305 ../gui/src/ws_gui_layout.c:542 +msgid "Zoom out" +msgstr "Pomniejsz" + +#: ../gui/src/ws_gui_layout.c:307 +msgid "Full screen" +msgstr "Pełen ekran" + +#: ../gui/src/ws_gui_layout.c:318 +msgid "Find" +msgstr "Znajdź" + +#: ../gui/src/ws_gui_layout.c:320 +msgid "Find next" +msgstr "Znajdź nastepne" + +#: ../gui/src/ws_gui_layout.c:322 +msgid "Find previous" +msgstr "Znajdź poprzednie" + +#: ../gui/src/ws_gui_layout.c:324 +msgid "Stop" +msgstr "Stop" + +#: ../gui/src/ws_gui_layout.c:639 ../gui/src/ws_gui_layout.c:790 +#: ../gui/src/ws_gui_layout.c:1100 +msgid "" +"\n" +".::GUI::. /apps/WhiteStork/Dictionaries does not exist!!" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:643 ../gui/src/ws_gui_layout.c:824 +msgid "Choose dictionaries" +msgstr "Wybierz słowniki" + +#: ../gui/src/ws_gui_layout.c:692 ../gui/src/ws_gui_layout.c:859 +#: ../gui/src/ws_gui_layout.c:1143 +msgid "cancel" +msgstr "anuluj" + +#: ../gui/src/ws_gui_layout.c:698 ../gui/src/ws_gui_layout.c:864 +msgid "ok" +msgstr "ok" + +#: ../gui/src/ws_gui_layout.c:812 +msgid "There are no dictionaries to optimize" +msgstr "Brak sowników do zoptymalizowania" + +#: ../gui/src/ws_gui_layout.c:990 +msgid "Would you like to activate this dictionary for use from now?" +msgstr "Czy chcesz teraz aktywować słownik?" + +#: ../gui/src/ws_gui_layout.c:1021 +msgid "" +"Would you like to optimize this dictionary to make it faster to search " +"within?" +msgstr "Czy chcesz zoptymalizować słownik teraz?" + +#: ../gui/src/ws_gui_layout.c:1045 +msgid "New dictionary has been added" +msgstr "Nowy sownik został dodany" + +#: ../gui/src/ws_gui_layout.c:1052 +msgid "Wrong dictionary file" +msgstr "Zły format sownika" + +#: ../gui/src/ws_gui_layout.c:1104 +msgid "Remove dictionaries" +msgstr "Usuń słownik" + +#: ../gui/src/ws_gui_layout.c:1149 +msgid "remove selected" +msgstr "Usuń zaznaczone" + +#: ../gui/src/ws_gui_layout.c:1212 +msgid "About" +msgstr "O programie" + +#: ../gui/src/ws_gui_layout.c:1231 +msgid "" +"Maemo Multilingual Dictionary\n" +"ver. 0.5" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1237 +msgid "" +"Copyright 2006, ComArch S.A\n" +"All rights reserved" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1266 +msgid "" +"The following third party\n" +"components may be\n" +"included depending \n" +"on your system configuration:\n" +"\n" +"D-BUS - License information:\n" +"http://opensource.org/licenses/academic.php" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1303 +msgid "Licence" +msgstr "Licencja" + +#: ../gui/src/ws_gui_layout.c:1323 +msgid "" +"Terms of use\n" +"\n" +"READ THE TERMS OF USE CAREFULLY BEFORE INSTALALTION OF THIS SOFTWARE. BY\n" +"INSTALALTION OF THIS SOFTWARE, YOU AGREE TO THE FOLLOWING TERMS OF USE.\n" +"\n" +"1. LICENSE TO USE. ComArch grants you a non-exclusive and non-transferable\n" +"license for the internal use only of the accompanying software and\n" +"documentation and any error corrections provided by ComArch (collectively " +"\"Software\"), by the one user.\n" +"\n" +"2. RESTRICTIONS. Software is confidential and copyrighted. Title to " +"Software\n" +"and all associated intellectual property rights is retained by ComArch\n" +"and/or its licensors. Unless enforcement is prohibited by applicable law,\n" +"you may not modify, decompile, or reverse engineer Software. You " +"acknowledge\n" +"that Software is not designed, licensed or intended for use in the design,\n" +"construction, operation or maintenance of any nuclear facility. Sun ComArch\n" +"disclaims any express or implied warranty of fitness for such uses. No\n" +"right, title or interest in or to any trademark, service mark, logo or " +"trade\n" +"name of ComArch or its licensors is granted under this terms of use.\n" +"\n" +"3. DISCLAIMER OF WARRANTY. UNLESS SPECIFIED IN THIS AGREEMENT TERMS OF USE,\n" +"ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, " +"INCLUDING\n" +"ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE " +"OR\n" +"NON-INFRINGEMENT ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT THESE " +"DISCLAIMERS\n" +"ARE HELD TO BE LEGALLY INVALID.\n" +"\n" +"4. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO " +"EVENT\n" +"WILL COMARCH OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR\n" +"DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE\n" +"DAMAGES, HOWEVER CAUSED REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT\n" +"OF OR RELATED TO THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF COMARCH\n" +"HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. In no event will\n" +"ComArch's liability to you, whether in contract, tort (including\n" +"negligence), or otherwise, exceed []. The foregoing limitations will apply\n" +"even if the above stated warranty fails of its essential purpose.\n" +"\n" +"5. Termination. This license is effective until terminated. You may\n" +"terminate this license at any time by destroying all\n" +"copies of Software.\n" +"This license will terminate immediately without notice from ComArch if you\n" +"fail to comply with any provision of this license. Upon Termination, you\n" +"must destroy all copies of Software.\n" +"\n" +"6. Export Regulations. All Software and technical data delivered under this\n" +"terms of use are subject to Polish export control laws and may be subject " +"to\n" +"export or import regulations in other countries. You agree to comply\n" +"strictly with all such laws and regulations and acknowledge that you have\n" +"the responsibility to obtain such licenses to export, re-export, or import\n" +"as may be required after delivery to you.\n" +"\n" +"7. Governing Law. Any action related to this license will be governed by\n" +"Polish Law.\n" +"\n" +"8. Severability. If any provision of this terms of use is held to be\n" +"unenforceable, this terms of use will remain in effect with the provision\n" +"omitted, unless omission would frustrate the intent of the parties, in " +"which\n" +"case this terms of use will immediately terminate.\n" +"\n" +"9. Integration. This document is the entire agreement between you and\n" +"ComArch relating to its subject matter. It supersedes all prior or\n" +"contemporaneous oral or written communications, proposals, representations\n" +"and warranties and prevails over any conflicting or additional\n" +"terms of any\n" +"quote, order, acknowledgment, or other communication between the parties\n" +"relating to its subject matter during the term of these terms of use. No\n" +"modification of this Agreement will be binding, unless in writing and " +"signed\n" +"by an authorized representative of each party." +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1325 +msgid "Agree" +msgstr "Zgadzam się" + +#: ../gui/src/ws_gui_layout.c:1330 +msgid "Disagree" +msgstr "Nie zgadzam się" diff --git a/po/template.po b/po/template.po new file mode 100644 index 0000000..0cbf6ea --- /dev/null +++ b/po/template.po @@ -0,0 +1,534 @@ +# 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: 2006-11-28 11:49+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../gui/src/ws_gui_layout.c:43 +msgid "ws_ni_welcome" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:46 ../gui/src/ws_gui_callbacks.c:143 +#: ../gui/src/ws_gui_callbacks.c:855 ../gui/src/ws_gui_callbacks.c:981 +msgid " " +msgstr "" + +#: ../gui/src/ws_gui_layout.c:64 ../gui/src/ws_gui_layout.c:1324 +msgid "WhiteStork" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:112 ../gui/src/ws_gui_layout.c:1334 +#: ../gui/src/ws_gui_layout.c:1341 +msgid "Tahoma 12" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:117 +msgid "url_requested" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:174 ../gui/src/ws_gui_layout.c:351 +msgid "ws_me_search_find" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:212 +msgid "search" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:217 +msgid "toggled" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:222 ../gui/src/ws_gui_layout.c:227 +#: ../gui/src/ws_gui_layout.c:231 +msgid "clicked" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:266 +msgid "ws_me_dictionaries" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:268 +msgid "ws_me_bookmarks" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:270 +msgid "ws_me_edit" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:272 +msgid "ws_me_view" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:274 +msgid "ws_me_search" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:276 +msgid "ws_me_about" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:278 +msgid "ws_me_close" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:285 +msgid "ws_me_dictionaries_load" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:287 +msgid "ws_me_dictionaries_select" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:289 +msgid "ws_me_dictionaries_remove" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:291 +msgid "ws_me_dictionaries_optimize" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:303 +msgid "ws_me_bookmarks_open" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:305 +msgid "ws_me_bookmarks_close" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:307 +msgid "ws_me_bookmarks_add" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:309 +msgid "ws_me_bookmarks_remove" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:321 +msgid "ws_me_edit_copy" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:323 +msgid "ws_me_edit_paste" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:325 +msgid "ws_me_edit_select_all" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:334 +msgid "ws_me_view_hide_words_list" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:336 +msgid "ws_me_view_zoom_in" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:338 +msgid "ws_me_view_zoom_out" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:340 +msgid "ws_me_view_fullscreen" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:353 +msgid "ws_me_search_find_next" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:355 +msgid "ws_me_search_find_prev" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:357 +msgid "ws_me_search_stop" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:410 ../gui/src/ws_gui_layout.c:415 +#: ../gui/src/ws_gui_layout.c:420 ../gui/src/ws_gui_layout.c:425 +#: ../gui/src/ws_gui_layout.c:429 ../gui/src/ws_gui_layout.c:434 +#: ../gui/src/ws_gui_layout.c:439 ../gui/src/ws_gui_layout.c:444 +#: ../gui/src/ws_gui_layout.c:449 ../gui/src/ws_gui_layout.c:454 +#: ../gui/src/ws_gui_layout.c:459 ../gui/src/ws_gui_layout.c:464 +#: ../gui/src/ws_gui_layout.c:469 ../gui/src/ws_gui_layout.c:474 +#: ../gui/src/ws_gui_layout.c:479 ../gui/src/ws_gui_layout.c:484 +#: ../gui/src/ws_gui_layout.c:489 ../gui/src/ws_gui_layout.c:494 +#: ../gui/src/ws_gui_layout.c:499 ../gui/src/ws_gui_layout.c:504 +#: ../gui/src/ws_gui_layout.c:509 ../gui/src/ws_gui_layout.c:515 +#: ../gui/src/ws_gui_layout.c:521 ../gui/src/ws_gui_layout.c:621 +#: ../gui/src/ws_gui_layout.c:626 ../gui/src/ws_gui_layout.c:631 +#: ../gui/src/ws_gui_layout.c:636 ../gui/src/ws_gui_layout.c:641 +#: ../gui/src/ws_gui_layout.c:645 +msgid "activate" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:560 +msgid "ws_mp_search" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:580 +msgid "ws_mp_edit_copy" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:585 +msgid "ws_mp_edit_paste" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:590 +msgid "ws_mp_edit_select_all" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:597 +msgid "ws_mp_edit" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:605 +msgid "ws_mp_zoom_in" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:610 +msgid "ws_mp_zoom_out" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:708 ../gui/src/ws_gui_layout.c:869 +#: ../gui/src/ws_gui_layout.c:1188 +msgid "" +"\n" +".::GUI::. /apps/WhiteStork/Dictionaries does not exist!!" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:713 ../gui/src/ws_gui_layout.c:905 +msgid "ws_ti_choose_dictionaries_title" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:742 ../gui/src/ws_gui_layout.c:795 +#: ../gui/src/ws_gui_layout.c:812 ../gui/src/ws_gui_layout.c:1066 +#: ../gui/src/ws_gui_callbacks.c:1519 ../gui/src/ws_gui_callbacks.c:1555 +#: ../gui/src/ws_gui_callbacks.c:1601 +msgid "/active" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:768 ../gui/src/ws_gui_layout.c:942 +#: ../gui/src/ws_gui_layout.c:1237 ../gui/src/ws_gui_layout.c:1433 +#: ../gui/src/ws_gui_layout.c:1501 +msgid "ws_db_cancel" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:774 ../gui/src/ws_gui_layout.c:947 +#: ../gui/src/ws_gui_layout.c:1428 ../gui/src/ws_gui_layout.c:1496 +msgid "ws_db_ok" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:793 ../gui/src/ws_gui_layout.c:810 +#: ../gui/src/ws_gui_layout.c:967 ../gui/src/ws_gui_layout.c:987 +#: ../gui/src/ws_gui_layout.c:1056 ../gui/src/ws_gui_layout.c:1064 +#: ../gui/src/ws_gui_layout.c:1099 ../gui/src/ws_gui_layout.c:1262 +msgid "/" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:877 ../gui/src/ws_gui_layout.c:969 +#: ../gui/src/ws_gui_layout.c:989 ../gui/src/ws_gui_layout.c:1101 +msgid "/optimized" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:893 +msgid "ws_ni_no_dictionaries_to_optimize" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1023 +msgid "ws_ti_load_dictionary_title" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1052 +msgid ".xdxf" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1056 +msgid "/path" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1075 +msgid "ws_ni_dictionaries_activation_question" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1108 +msgid "ws_ni_dictionaries_optimalization_question" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1133 +msgid "ws_ni_dictionary_added" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1140 +msgid "ws_ni_dictionary_wrong_file" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1193 +msgid "ws_ti_remove_dictionaries_title" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1230 ../gui/src/ws_gui_callbacks.c:1522 +#: ../gui/src/ws_gui_callbacks.c:1558 +msgid "bookmarks" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1244 +msgid "ws_bd_remove_dictionaries_remove_selected" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1311 +msgid "ws_ti_about_title" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1321 +msgid "/usr/share/pixmaps/whitestork.png" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1325 +msgid "Tahoma 18" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1327 +msgid "__________" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1330 +msgid "" +"Maemo Multilingual Dictionary\n" +"ver. " +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1339 +msgid "" +"Copyright 2006, ComArch S.A\n" +"All rightsreserved" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1361 +msgid "Tahoma 10" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1369 +msgid "" +"The following third party\n" +"components may be\n" +"included depending \n" +"on your system configuration:\n" +"\n" +"D-BUS - License information:\n" +"http://opensource.org/licenses/academic.php" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1407 +msgid "ws_ti_add_bookmark" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1419 +msgid "ws_ti_bookmarks_add_question" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1449 +msgid "ws_ni_bookmark_added" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1457 +msgid "ws_ni_bookmark_not_added" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1475 +msgid "ws_ti_remove_bookmark" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1487 +msgid "ws_ni_remove_bookmark_question" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1515 +msgid "ws_ni_bookmark_removed" +msgstr "" + +#: ../gui/src/ws_gui_layout.c:1522 +msgid "ws_ni_bookmark_not_removed" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:44 +#, c-format +msgid "XDXF->%s() start counting time for function '%s()'.\n" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:74 +#, c-format +msgid "XDXF->%s() function '%s()' was working for: %g [s] or %ld [us].\n" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:114 +msgid "ws_ni_error_occured" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:119 +msgid "response" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:133 +msgid "ws_ni_no_dictionary_available" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:168 +msgid "ws_pb_caching" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:212 +msgid "ws_ni_dictionary_unavailable" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:289 +msgid "ws_ni_no_words_found" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:759 +msgid "Name" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:761 +msgid "text" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:858 ../gui/src/ws_gui_callbacks.c:910 +#: ../gui/src/ws_gui_callbacks.c:916 ../gui/src/ws_gui_callbacks.c:961 +msgid "prefix" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:868 +msgid "ws_ni_no_text_selected" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:914 +msgid "\n" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:971 +msgid "ws_ab_searching" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:988 +msgid "ws_ni_no_word_typed" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1009 +msgid "ws_ni_search_aborted" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1113 +msgid "file:" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1161 +msgid "button-press-event" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1269 ../gui/src/ws_gui_callbacks.c:1271 +#: ../gui/src/ws_gui_callbacks.c:1284 +msgid "" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1278 +msgid "" +"
" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1290 ../gui/src/ws_gui_callbacks.c:1292 +#: ../gui/src/ws_gui_callbacks.c:1300 +msgid "" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1298 +msgid "
" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1306 ../gui/src/ws_gui_callbacks.c:1308 +#: ../gui/src/ws_gui_callbacks.c:1317 +msgid "" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1314 +msgid "" +"
" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1323 ../gui/src/ws_gui_callbacks.c:1325 +#: ../gui/src/ws_gui_callbacks.c:1333 +msgid "" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1331 +msgid "

" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1340 +msgid "
" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1369 +msgid "" +"\n" +".::GUI::. Bookmark mode on\n" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1394 +msgid "" +"\n" +".::GUI::. Bookmark mode off\n" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1422 +msgid "ws_ni_select_word_to_add" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1436 +#, c-format +msgid ".::GUI::. LAST_WORD: \"%s\"" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1446 +msgid "ws_ni_select_word_to_remove" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1521 ../gui/src/ws_gui_callbacks.c:1557 +#, c-format +msgid "" +"\n" +"\n" +"slownik (%d): %s - active: %d" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1530 ../gui/src/ws_gui_callbacks.c:1566 +#, c-format +msgid "" +"\n" +"\n" +"Po przestawieniu: slownik (%d): %s - active: %d" +msgstr "" + +#: ../gui/src/ws_gui_callbacks.c:1603 +#, c-format +msgid "" +"\n" +"\n" +"slownik (%d): %s - \n" +"active: %d" +msgstr "" diff --git a/po/whitestork.mo b/po/whitestork.mo new file mode 100644 index 0000000000000000000000000000000000000000..17b8b35e3a26fd123e745cc4df27cc9bcc348b0e GIT binary patch literal 2955 zcmaKsO>7)B6vqveuPqc>XrVyCKua6SY&Qi;wDf~CA8JLKEX}5oazWl1XV<&4_R2Gp zWd^Ad5fu^_RHRBoaNq(QK|)BVh!fchT!3CcLI{aVPjH1x#sAIBZZ@=FjpsM^*na=_ z{On(MY`MfxN~n*ZesB|G6ZCxxUML5)Fm@|A0^R{0%G+b$y=Wf??*r%Zeiy{U6kd0M z8r%iG4$}O0K|JjJoF9UBqWuwgH~1-d8~8Q26oW@?f0Mh*PSd8Yq z4N_d!!0q72Illxklzj`5ogYDp>(3zR`W>V={hj|W;3tjW4$?Zi!5!d15Dzs^2$G%? zAjSU`@Ja9-ct4ncwB9@5A@CA71@=Iiw-v#{(ri!8{UF6}6fd%O3?vqaH+k2$lA)U*LY~2kjC0M}_i>3dNCp<*2lGRGvbmJbMC_ z;!m-oIPXKHqkjN(QyH(BC}iooSS+&fx|NcRYc8!dmK)cNtn}DK! z`92R^2-577@+9vX>jm6bLC9v5E43@xj1k_3teDNp?og9AM8Ip9&xPl~jakD(nB#%; zr5k1)v?vebj`WK3KeMrHBIujzgsQEQ&3!qrP;;ycE`Luna@G zYQ~a~`BV`f_x=9oaICWxLepW@hP09kRBbjK#dh$}aFgrJN2y@bpqMW!A9Dvga!$!E zTQrgH@z_L&YfI890(-n7LVP!{!axS5BOxMW!Ll`NtlT|ugUNjf*Gp+N@F=|bbXUW2xdzL=9JDz$?6Ih!|Q2KT!Ad`nbaOP%N&A3V`GNcWc#Qz zgvdd^X)&Aa*&qWl3H{|N)-;hB&S}p%CvAXSFY{9I`C_SXR(7yc&Y7UDJm+Lo51gtg z^O>k6f}~gxT}1CC*R*Mqi(sKLS9K<=6m(vkNrbb^50^?uoY9hV_&GjWDnC1Ru!J5A zbj~90$=3gln?cl^sueo$1)S{L=9z7N^gpE>FU$yCk3?NMRVmtKUNJaAjl!AJXQnp1 z9EFb)Mu$?v3Qj{gJt>DezEJu_?ly!CWO!_$I_->Yj3YJ6(mGSxH6CJE=3_M#7T6rl zvZ-6qR&w~8PR>$Yc!_B9K&`K_#W)DpFLYFImDhT!>lZxq)ReRd4|=Pnt5r*}CDCqa z)nqT5j*6OWe(2!9r^tjSE0Yo($WV@?y6s*pe1auXnjmt`Sa}f&9w;@Q&%& zM0!}Q--SDT7HOC9wD4tult{bD&Js>m+!nq{q75sGEw+5wWD7ymdvjo0 zUDuvZkf%*nfqwx$Rad}EE_CD@d>X_!6~?`f#wGRcJo-i>o1>u>Qcu3scXzOfNExR0e3$?*7OU<8UW z2YEV}!E5oq*3$~>C2`GF2+mS(HNCsqBFuELis>TzT0w%ZHX_l)*YKr6fkCRZ4F0+K h<)IX-k!Pt)NY1Vr^un(w4S&+#-I$SYX^1J~{{h2X@p}LO literal 0 HcmV?d00001 diff --git a/src/bookmarks/bdb/COPYING b/src/bookmarks/bdb/COPYING new file mode 100755 index 0000000..fb6319b --- /dev/null +++ b/src/bookmarks/bdb/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, 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 Lesser 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. + + GNU GENERAL PUBLIC LICENSE + 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. + + + Copyright (C) + + 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. + +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. + + , 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 Lesser General +Public License instead of this License. \ No newline at end of file diff --git a/src/bookmarks/bdb/Makefile b/src/bookmarks/bdb/Makefile new file mode 100755 index 0000000..497fc84 --- /dev/null +++ b/src/bookmarks/bdb/Makefile @@ -0,0 +1,71 @@ +COMPILER = gcc +#DEBUG = -Wall -g -DNOLOGS +DEBUG = -Wall -g +SOURCES = ./src +INCLUDE = ./include +LIBS = `pkg-config --libs glib-2.0 gmodule-2.0` -ldb1 +FLAGS = `pkg-config --cflags glib-2.0 gmodule-2.0` -I${INCLUDE} -I./.. -I../../../include +BINARIES = bin +FINAL = ws_bookmark.so + +first: clean ${FINAL} bdbprint + +show1: + ./bdbprint s data/bm_words.db + +show2: + ./bdbprint b data/bm_trans.db + +bdbprint: ${SOURCES}/berkeleyRead.c + @echo -en "Berkeley DB reader building ...\n" + gcc ${DEBUG} `pkg-config --cflags --libs glib-2.0` -ldb1 $< -o $@ + +${FINAL}: bookmark.o ${SOURCES}/engine_bookmark.c + gcc ${DEBUG} -shared -fPIC ${FLAGS} ${LIBS} bookmark.o -o ${FINAL} + cp ${FINAL} ../../../bin + +bookmark.o: ${SOURCES}/engine_bookmark.c + gcc ${DEBUG} -c -fPIC -o bookmark.o ${SOURCES}/engine_bookmark.c ${FLAGS} + +clean: + @-rm -f ${BINARIES}/* + @-rm -f ${SOURCES}/test + @-rm -f ${SOURCES}/*~ + @-rm -f *~ + @-rm -f ${INCLUDE}/*~ + @-rm -f ${SOURCES}/${FINAL} + @-rm -f ${SOURCES}/testDatabase + @-rm -f ws_bookmark.so bookmark.o bdbprint + @echo -e -n "Project 'BookmarkEngine' directories has been cleaned.\n" + + + +cleandata: bdbprint + @-rm -f ws_bookmarks-journal + @-rm -f ws_bookmarks + @-rm -f data/bm_words.db data/bm_trans.db + @./bdbprint s data/bm_words.db + @./bdbprint b data/bm_trans.db add 0 1 + + +data: ${SOURCES}/testMakeDatabase.c + @echo -e -n "Compiling testDatabase...\n" + @gcc ${DEBUG} -o ${SOURCES}/testDatabase ${SOURCES}/testMakeDatabase.c ${FLAGS} ${LIBS} + +datarun: data + @run-standalone.sh src/testDatabase + +test: test.o + @echo "Linking test program..." + @gcc ${LIBS} ${DEBUG} -o ${SOURCES}/test ${BINARIES}/test.o + @echo -e "Building test program finished.\n" + +test.o: + @echo "Compiling test program..." + @gcc ${FLAGS} ${DEBUG} -c -o ${BINARIES}/test.o ${SOURCES}/test.c + +check: + @echo "Running test program:" + @run-standalone.sh ${SOURCES}/test + + \ No newline at end of file diff --git a/src/bookmarks/bdb/data/bm_trans.db b/src/bookmarks/bdb/data/bm_trans.db new file mode 100755 index 0000000000000000000000000000000000000000..7abe57a73c139b1959fe8851353254f053fa1320 GIT binary patch literal 8192 zcmeI#yA6OK6a~=dug1#S6r8A3o!SV41c0^CsXPRDsHF-6H*w>$e=oCF9EAV7cs z0RjXF5FkK+z%K-bZi=z=Epp1KyHp7fAV7cs0RjXF5FkK+0D(^l%;mLpwLBmH3rWrb AQIGPeOjIx-(V*| zfB*pk1PBlyK!5-N0t9{`P-M3#V;fhh~7cKS#1poj5 literal 0 HcmV?d00001 diff --git a/src/bookmarks/bdb/include/.kateconfig b/src/bookmarks/bdb/include/.kateconfig new file mode 100755 index 0000000..7f9ed54 --- /dev/null +++ b/src/bookmarks/bdb/include/.kateconfig @@ -0,0 +1 @@ +kate hl Sources/C; \ No newline at end of file diff --git a/src/bookmarks/bdb/include/engine_bookmark.h b/src/bookmarks/bdb/include/engine_bookmark.h new file mode 100755 index 0000000..a4c7ea2 --- /dev/null +++ b/src/bookmarks/bdb/include/engine_bookmark.h @@ -0,0 +1,238 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#ifndef _DICTIONARY_ENGINE_BOOKMARK +#define _DICTIONARY_ENGINE_BOOKMARK + +#ifdef __cplusplus + extern "C" { +#endif + +//______________________________________________________________________________ +// ***************************************************************************** +//************************************************************* HEADERS SECTION: +//------------------------------------------------------------------------------ +// headers with unix types/functions - only for timers +#include +#include +#include +#include +#include +//------------------------------------------------------------------------------ +// header with GLIB definitions/functions/types +#include +//------------------------------------------------------------------------------ +// header wit engine API +#include "dictionary_engine.h" +//------------------------------------------------------------------------------ +// header wit sqlite 2.x API +#include +//------------------------------------------------------------------------------ +#include + +//______________________________________________________________________________ +// ***************************************************************************** +//********************************************************* DEFINITIONS SECTION: +//------------------------------------------------------------------------------ +// definitions for timer function - flag telling if we want to start or stop +// timing +#define TIMER_START TRUE +#define TIMER_STOP FALSE +//------------------------------------------------------------------------------ +// definitions of version and format which engine handles +static const gchar* DIC_ENG_VERSION = "0.2"; +static const gchar* DIC_ENG_FORMAT = "Users' Bookmarks"; +static const gchar* DIC_ENG_DESCRIPTION = "This module handles users' " + "bookmarks. Based on Berkeley DB 1.85"; + +//------------------------------------------------------------------------------ +// macro for "printing" gboolean statement - "TRUE" or "FALSE" +#define PRINT_STATE(state) ( (state) ? "TRUE" : "FALSE" ) +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//****************************************** DATA STRUCTURE DEFINITIONS SECTION: +//------------------------------------------------------------------------------ +/** \brief Internal data structure of XDXF Engine. + */ +struct _BookData { + DB* db_words; + DB* db_trans; + BTREEINFO info_words; + BTREEINFO info_trans; + guint freeID; + + + + gchar* dict_path; + EngineStatus last_error; + gboolean auto_free; + + cb_progress cb_progress_caching; + gpointer cb_progress_caching_data; + gdouble cb_progress_caching_seed; + + cb_progress cb_progress_word_list; + gpointer cb_progress_word_list_data; + gdouble cb_progress_word_list_seed; + + cb_progress cb_progress_word_trans; + gpointer cb_progress_word_trans_data; + gdouble cb_progress_word_trans_seed; + + cb_word_list cb_search_word_list; + gpointer cb_search_word_list_data; + + cb_word_translation cb_search_word_trans; + gpointer cb_search_word_trans_data; +}; +typedef struct _BookData BookData; +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//************************************************ ADDITIONAL FUNCTIONS SECTION: +//------------------------------------------------------------------------------ +// returning concrete part of file +//static gchar* read_file_part(FilePart* part, GnomeVFSHandle* file); +//------------------------------------------------------------------------------ +// convert string to proper path name (no filename, no "/" at the ned, file +// exist) +static gchar* string_to_path(gchar** string); +//------------------------------------------------------------------------------ +// tells if file is in Bookark Berkeley DB format (file should exist) +static gboolean is_Bookmark_db_file(gchar* file); +//------------------------------------------------------------------------------ +// start/stop timers - returnet -1.0 if we start or seconds passed from start +// if we want to stop timer +static double bm_timer(gboolean start, gchar* message); +//------------------------------------------------------------------------------ +// create and add new entry to databases +static gboolean bm_add_new_entry(gchar* word, + gchar* translation, + BookData* data); +//------------------------------------------------------------------------------ +// load current minimal available free ID fortranslations +static void bm_load_freeID(BookData* data); +//------------------------------------------------------------------------------ +// save current minimal available free ID fortranslations +static void bm_save_freeID(BookData* data); +//------------------------------------------------------------------------------ +// save translation in database under id +static gboolean bm_add_only_translation(BookData* data, + gchar* translation, + guint id); +//------------------------------------------------------------------------------ +static gint bm_compare_key_trans(const DBT *a, const DBT *b); +static gint bm_compare_key_words(const DBT *a, const DBT *b); +//______________________________________________________________________________ +// ***************************************************************************** +//****************************************************** MAIN FUNCTIONS SECTION: +//------------------------------------------------------------------------------ +gboolean bm_engine_add_word(Engine* engine, + gchar* word, + gchar* translation); +//------------------------------------------------------------------------------ +gboolean bm_engine_remove_word(Engine* engine, + gchar* word); +//------------------------------------------------------------------------------ +gchar* bm_engine_get_lang_from(Engine* engine); +//------------------------------------------------------------------------------ +gchar* bm_engine_get_lang_to(Engine* engine); +//------------------------------------------------------------------------------ +gchar* bm_engine_get_title(Engine* engine); +//------------------------------------------------------------------------------ +gchar* bm_engine_get_icon_path(Engine* engine); + + + +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_check(module,location) function +gboolean bm_engine_check(gchar* location); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_get_description(module) function +gchar* bm_engine_description(); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_get_format(module) function +gchar* bm_engine_format(); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_get_version(module) function +gchar* bm_engine_version(); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_create(module,location,flags) and +// dict_eng_module_create_ext(module,location,flags) functions +Engine* bm_engine_create(gchar* location, + EngineOptimizationFlag flags, + cb_progress progress_handler, + gpointer progress_data, + gdouble seed); +//------------------------------------------------------------------------------ +// implementation of dict_eng_destroy(engine) function +void bm_engine_close(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_get_location(engine) function +gchar* bm_engine_location(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_optimize(engine) function +void bm_engine_optimize(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_is_optimized( engine ) function +gboolean bm_engine_is_optimized(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_set_auto_free(engine, state) function +void bm_engine_set_auto_free(Engine* engine, gboolean state); +//------------------------------------------------------------------------------ +// implementation of dict_eng_set_callback(engine,signal,c_handler,data) +// function +gpointer bm_engine_set_callback(Engine* engine, + gchar* event, + gpointer c_handler, + gpointer user_data); +//------------------------------------------------------------------------------ +// implementation of dict_eng_set_progress_seed(engine, signal, val) function +void bm_engine_set_progress_seed(Engine* engine, + gchar* signal, + gdouble seed); +//------------------------------------------------------------------------------ +// implementation ofdict_eng_search_word_list(engine,pattern) function +void bm_engine_search_word_list(Engine* engine, + gchar* pattern, + gpointer data); +//------------------------------------------------------------------------------ +// implementation of dict_eng_search_word_translation(engine,word) function +void bm_engine_search_word_translation(Engine* engine, + gchar* word, + gpointer data); +//------------------------------------------------------------------------------ +// implementation of dict_eng_get_last_state(engine) function +EngineStatus bm_engine_status(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_state_message(error) function +gchar* bm_engine_status_message(EngineStatus error); +//------------------------------------------------------------------------------ +// implementation of engine_global_functions(void) function +EngineModule engine_global_functions(); + +#ifdef __cplusplus +} +#endif +#endif /* #ifndef _DICTIONARY_ENGINE_STARDICT */ diff --git a/src/bookmarks/bdb/src/.kateconfig b/src/bookmarks/bdb/src/.kateconfig new file mode 100755 index 0000000..7f9ed54 --- /dev/null +++ b/src/bookmarks/bdb/src/.kateconfig @@ -0,0 +1 @@ +kate hl Sources/C; \ No newline at end of file diff --git a/src/bookmarks/bdb/src/berkeleyRead.c b/src/bookmarks/bdb/src/berkeleyRead.c new file mode 100644 index 0000000..5145db5 --- /dev/null +++ b/src/bookmarks/bdb/src/berkeleyRead.c @@ -0,0 +1,504 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + + +typedef unsigned int uint; + +static int bm_compare_key_trans(const DBT *a, const DBT *b) { + uint* tmpa = (uint*)(a->data); + uint* tmpb = (uint*)(b->data); + + if((*tmpa) == (*tmpb)) return 0; + if(*tmpa > *tmpb) return 1; + else return -1; +} +//------------------------------------------------------------------------------ +static int bm_compare_key_words(const DBT *a, const DBT *b) { + char* tmpa = g_utf8_casefold((char*)(a->data),-1); + char* tmpb = g_utf8_casefold((char*)(b->data),-1); + int result = g_utf8_collate(tmpa,tmpb); + g_free(tmpa); + g_free(tmpb); + return result; +} + +//------------------------------------------------------------------------------ +int read_berkeley_in_string_mode(DB* dbp) { + DBT key = { NULL , 0 }; + DBT val = { NULL , 0 }; + + int result = dbp->seq(dbp, &key, &val, R_FIRST); + uint count = 1; + uint a = 0; + uint b = 0; + uint c = 0; + uint i = 0; + uint* t = NULL; + while(1 != result) { + if(-1 == result) { + printf("---Error! While sequentiall reading database\n"); + return 10; + }; + memcpy(&a, val.data, sizeof(uint)); + t = (uint*)(val.data + sizeof(uint)); + printf("%4d. word = %-30s [%-2d record(s)] => \n",count, (char*)(key.data), a); + + for(i=0; i < a; ++i) { + b = t[i*2]; + c = t[i*2 + 1]; + printf("\t%4u.%u. ID = %u [hash = %#x]\n",count,i+1,b,c); + } + + result = dbp->seq(dbp, &key, &val, R_NEXT); + ++count; + } + return 0; +} +//------------------------------------------------------------------------------ +int read_berkeley_in_binary_mode(DB* dbp) { + DBT key = { NULL , 0 }; + DBT val = { NULL , 0 }; + + uint count = 1; + uint a = 0; + char* s = NULL; + int result = dbp->seq(dbp, &key, &val, R_FIRST); + while(1 != result) { + if(-1 == result) { + printf("---Error! While sequentiall reading database\n"); + return 10; + }; + memcpy(&a, key.data, sizeof(uint)); + s = (char*) (val.data); + if(a == 0) { + uint b = 0; + memcpy(&b , val.data, sizeof(uint)); + printf("%4u. ID = %-4u value(freeID)=%u\n",count,a,b); + } + else { + printf("%4u. ID = %-4u string=\'%s\'\n",count,a,s); + } + + result = dbp->seq(dbp, &key, &val, R_NEXT); + ++count; + } + return 0; +} +//------------------------------------------------------------------------------ +int berkeley_del_record(DB* dbp,char mode,char* id) { + uint a; + DBT key = { NULL , 0 }; + if('s' == mode) { + printf("Delete key: %s...",id); + key.data = id; + key.size = strlen(id) + 1; + } + else if('b' == mode) { + if(1 != sscanf(id,"%u",&a)) { + printf("ID has wrong format - it should be unsigned int!\n"); + return 25; + }; + printf("Deleting record with id=%u\n",a); + key.size = sizeof(uint); + key.data = &a; + } + else { + printf("not supported mode for delete action!\n"); + return 24; + }; + + int result = dbp->del(dbp,&key,0); + if(1 == result) { + printf("... there was no such an element!\n"); + } + else if(-1 == result) { + printf("---Error while deleteing record!\n"); + return 29; + } + else { + printf("... record deleted!\n"); + } + + return 0; +} +//------------------------------------------------------------------------------ +int berkeley_fnd_record(DB* dbp,char mode,char* id) { + uint a = 0; + DBT key = { NULL , 0 }; + DBT val = { NULL , 0 }; + if('s' == mode) { + printf("Searching for key: %s...\n",id); + key.data = id; + key.size = strlen(id) + 1; + } + else if('b'== mode) { + if(1 != sscanf(id,"%u",&a)) { + printf("ID has wrong format - it should be unsigned int!\n"); + return 35; + }; + printf("Searching for record with id=%u\n",a); + key.size = sizeof(uint); + key.data = &a; + } + else { + printf("not supported mode for find action!\n"); + return 30; + }; + + int result = dbp->get(dbp,&key,&val,0); + if(1 == result) { + printf("... there was no such a record\n"); + } + else if(-1 == result) { + printf("---Error while searching for the record!\n"); + return 29; + } + else { + uint* t = NULL; + uint b = 0, c = 0, i = 0; + char* s = NULL; + switch(mode) { + case 's': +// ------------------------------ + memcpy(&a, val.data, sizeof(uint)); + t = (uint*)(val.data + sizeof(uint)); + printf("Element word = %-30s [%-2d record(s)] => \n", (char*)(key.data), a); + + for(i=0; i < a; ++i) { + b = t[i*2]; + c = t[i*2 + 1]; + printf("\t%2u. ID = %u [hash = %#xu]\n",i+1,b,c); + } + break; +// ------------------------------ + case 'b': +// ------------------------------ + s = (char*) (val.data); + if(a == 0) { + memcpy(&b , val.data, sizeof(uint)); + printf("Element ID = %-4u value(freeID)=%u\n",a,b); + } + else { + printf("Element ID = %-4u string=\'%s\'\n",a,s); + } + break; +// ------------------------------ + default: + printf("Not supported mode!\n"); + return 30; + } + } + return 0; +} +//------------------------------------------------------------------------------ +int berkeley_fnd_pattern_record(DB* dbp,char mode,char* id) { + DBT key = { NULL , 0 }; + DBT val = { NULL , 0 }; + + if('s' == mode) { + int result = dbp->seq(dbp, &key, &val, R_FIRST); + uint count = 1; + uint a = 0; + uint b = 0; + uint c = 0; + uint i = 0; + uint* t = NULL; + char* tmp = g_utf8_casefold(id,-1); + uint len = strlen(tmp); + printf("dlugosc: %u\n",len); + char* tmp2 = NULL; + while(1 != result) { + if(-1 == result) { + printf("---Error! While sequentiall reading database\n"); + return 10; + }; + tmp2 = g_utf8_casefold((char*)(key.data),len); + if(0 == g_utf8_collate(tmp2,tmp) || len == 0) { + memcpy(&a, val.data, sizeof(uint)); + t = (uint*)(val.data + sizeof(uint)); + printf("%4d. word = %-30s [%-2d record(s)] => \n",count, (char*)(key.data), a); + + for(i=0; i < a; ++i) { + b = t[i*2]; + c = t[i*2 + 1]; + printf("\t%4u.%u. ID = %u [hash = %#xu]\n",count,i+1,b,c); + } + } + result = dbp->seq(dbp, &key, &val, R_NEXT); + ++count; + } + free(tmp); + return 0; + } + else { + printf("Searching for pattern is not supported in binary mode!"); + return 65; + } +} +//------------------------------------------------------------------------------ +int berkeley_del_pattern_record(DB* dbp,char mode,char *id) { + DBT key = { NULL , 0 }; + DBT val = { NULL , 0 }; + + if('s' == mode) { + int result = dbp->seq(dbp, &key, &val, R_FIRST); + uint count = 0; + uint a = 0; + uint b = 0; + uint c = 0; + uint i = 0; + uint* t = NULL; + char* tmp = g_utf8_casefold(id,-1); + uint len = strlen(tmp); + char* tmp2 = NULL; + while(1 != result) { + if(-1 == result) { + printf("---Error! While sequentiall reading database\n"); + return 10; + }; + tmp2 = g_utf8_casefold((char*)(key.data),len); + if(0 == g_utf8_collate(tmp2,tmp) || len == 0) { + // delete actual record + + memcpy(&a, val.data, sizeof(uint)); + t = (uint*)(val.data + sizeof(uint)); + printf("Deleting record %4d. word = %-30s [%-2d record(s)] => \n",count, (char*)(key.data), a); + + for(i=0; i < a; ++i) { + b = t[i*2]; + c = t[i*2 + 1]; + printf("\t%4u.%u. ID = %u [hash = %#xu]\n",count,i+1,b,c); + } + int result = dbp->del(dbp,&key,0); + if(1 == result) { + printf("---Error find element but could not delete it!\n"); + } + else if(-1 == result) { + printf("---Error while deleteing record!\n"); + return 29; + } + else { + printf("... record deleted!\n"); + } + count++; + } + free(tmp2); tmp2 = NULL; + result = dbp->seq(dbp, &key, &val, R_NEXT); + } + printf("%u record were deleted totaly.\n",count); + free(tmp); + return 0; + } + else { + printf("Searching for pattern is not supported in binary mode!"); + return 65; + } +} +//------------------------------------------------------------------------------ +int berkeley_add_record(DB* dbp,char mode,char* id, char* value) { + DBT key = { NULL , 0 }; + DBT val = { NULL , 0 }; + + int result = 0; + uint a = 0, i = 0, error = 0, b = 0, c = 0; + uint* t = NULL; + char* tmp = malloc(200); + char* tmp_original = tmp; + if('s' == mode) { + printf("Adding record with key = %s...\n",id); + key.data = id; + key.size = strlen(id) + 1; + while(1) { + if(2 != sscanf(value,"%u%[ 0-9]",&a,tmp)) { + result = 43; + break; + } + val.size = sizeof(uint) * (a*2 + 1); + t = (uint*)malloc( val.size ); + t[0] = a; + for(i=0; i< a; ++i) { + if(2 != sscanf(tmp,"%u%[ 0-9]",&b,tmp)) { + error = 1; + break; + }; + t[1+i*2] = b; + int n = sscanf(tmp,"%u%[ 0-9]",&b,tmp); + if(( (2 != n) && (i!=(a-1)) ) || ((1!=n) && (i==(a-1)))) { + error = 1; + break; + }; + t[1+i*2+1] = b; + } + if(error) { + printf("Wrong value for string database!\n"); + result = 44; + break; + } + val.data = t; + break ;} + } + else if('b'== mode) { + if(1 != sscanf(id,"%u",&a)) { + printf("ID has wrong format - it should be unsigned int!\n"); + return 45; + }; + printf("Adding record with id=%u\n",a); + key.size = sizeof(uint); + key.data = &a; + if(0 == a) { + if(1 != sscanf(value,"%u",&c)) { + printf("Value has wrong format for record with ID=0 (freeID - unsinged int)\n"); + return 46; + }; + val.size = key.size; + val.data = &c; + } + else { + val.size = strlen(value) + 1; + val.data = value; + } + } + else { + printf("---Not supported mode for add action!\n"); + return 40; + }; + + if(0 != result) { + if(t) free(t); + free(tmp_original); + return result; + } + + result = dbp->put(dbp, &key, &val, R_NOOVERWRITE); + if(1 == result) { + printf("Such a key already exist in database!\n"); + result = 41; + } + else if(-1 == result) { + printf("---Error while adding new record!\n"); + result = 49; + } + else { + printf("New record has been added.\n"); + if(-1 == dbp->sync(dbp, 0)) { + printf("---Error while saving data to file! Record could be lost.\n"); + result = 48; + } + } + if(t) free(t); + return result; +} +//------------------------------------------------------------------------------ +int main(int argc, char* argv[]) { + int help = 0, i = 0; + for(i=1;i 1) || ( ('s' != _mode[0]) && ('b' != _mode[0]) )) { + printf("Wrong mode! Mode could be only s or b [\'s\' , \'b\']!\n"); + return 2; + } + char mode = _mode[0]; + + BTREEINFO info = { + 0, /* permit duplicate keys? */ + 0, /* cache size; 0 - default size */ + 0, /* page size; 0 - default */ + 0, /* byte order; 0 - use host order */ + 0, /* min page number per page; 0 - default=2 */ + bm_compare_key_words, /* comparision function */ + NULL /* prefix comparision function */ + }; + if('b' == mode) { + info.compare = bm_compare_key_trans; + } + u_int32_t flags = O_CREAT | O_RDWR; + DB *dbp = dbopen(filename, flags, 0755, DB_BTREE, &info); + if(NULL == dbp) { + printf("Could not open database: %s!\n",filename); + return 1; + }; + + int result = 0; + if(argc == 3) { + printf("Printing database: \'%s\' in mode %s :\n", filename, _mode); + if('s' == mode) { + result = read_berkeley_in_string_mode(dbp); + } + else if('b' == mode) { + result = read_berkeley_in_binary_mode(dbp); + } + } + else if(argc > 3) { + printf("Do not print - only action... [mode=%s]\n",_mode); + if(argc < 5) { + printf("Wrong number of parameters! probably You did not give id of record for action.\n"); + return 21; + }; + char* action = argv[3]; + if(strcmp(action,"del") == 0) { + if('*' == argv[4][0]) { + result = berkeley_del_pattern_record(dbp,mode,&(argv[4][1])); + } + else { + result = berkeley_del_record(dbp,mode,argv[4]); + } + } + else if(strcmp(action,"fnd") == 0) { + if('*' == argv[4][0]) { + result = berkeley_fnd_pattern_record(dbp,mode,argv[4]+1); + } + else { + result = berkeley_fnd_record(dbp,mode,argv[4]); + } + } + else if(strcmp(action,"add") == 0) { + if(argc < 6) { + printf("You did not give value for new record!\n"); + return 22; + }; + result = berkeley_add_record(dbp,mode,argv[4],argv[5]); + } + else { + printf("Not supported action: %s! The only good values are: add, del, fnd.\n",action); + result = 20; + } + } + + dbp->close(dbp); + return result; +} +//------------------------------------------------------------------------------ diff --git a/src/bookmarks/bdb/src/engine_bookmark.c b/src/bookmarks/bdb/src/engine_bookmark.c new file mode 100755 index 0000000..0777316 --- /dev/null +++ b/src/bookmarks/bdb/src/engine_bookmark.c @@ -0,0 +1,1368 @@ +/****************************************************************************** +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +******************************************************************************/ + +// header with data structure and function definition for XDXF engine. +// Also Engine API. +#include "engine_bookmark.h" +//------------------------------------------------------------------------------ + +#ifndef NOLOGS + #include + #define LOGS g_debug +#else + #define LOGS(frm,...) while(FALSE) +#endif + + +//------------------------------------------------------------------------------ +static gint bm_compare_key_trans(const DBT *a, const DBT *b) { + guint tmpa;// = (guint*)(a->data); + guint tmpb;// = (guint*)(b->data); + memcpy(&tmpa, a->data, sizeof(guint)); + memcpy(&tmpb, b->data, sizeof(guint)); + + if(tmpa == tmpb) return 0; + if(tmpa > tmpb) return 1; + else return -1; +} +//------------------------------------------------------------------------------ +static gint bm_compare_key_words(const DBT *a, const DBT *b) { + gchar* tmpa = g_utf8_casefold((gchar*)(a->data),-1); + gchar* tmpb = g_utf8_casefold((gchar*)(b->data),-1); + gint result = g_utf8_collate(tmpa,tmpb); + eg_free(tmpa); + eg_free(tmpb); + return result; +} +//------------------------------------------------------------------------------ +static void bm_save_freeID(BookData* data) { + LOGS("Saveing new freeID=%u...\n",data->freeID); + guint temp = 0; + DBT key = { &temp , sizeof(guint)}; + DBT val = { &(data->freeID) , sizeof(guint) }; + + gint res = data->db_trans->del(data->db_trans, &key, 0); + if(-1 == res) + { + data->last_error = ENGINE_INTERNAL_ERROR; + LOGS("Error while trying to delete old freeID!\n"); + return; + } + else { + LOGS("Old freeID=%u deleted successfully!\n",data->freeID-1); + } + + res = data->db_trans->put(data->db_trans, &key, &val, R_NOOVERWRITE); + if(-1 == res || 1 == res) + { + data->last_error = ENGINE_INTERNAL_ERROR; + LOGS("Error while trying to write new value for freeID!\n"); + } + else { + LOGS("New freeID=%u written successfully!\n",data->freeID); + } + + res = data->db_trans->sync(data->db_trans, 0); + if(-1 == res || 1 == res) + { + data->last_error = ENGINE_INTERNAL_ERROR; + LOGS("Error while trying to write data to fuile!\n"); + } + else { + LOGS("New data saved successfully to file!\n"); + } +} +//------------------------------------------------------------------------------ +static void bm_load_freeID(BookData* data) { + guint temp = 0; + DBT key = { &temp , sizeof(guint) }; + DBT val = { NULL , 0 }; + + gint res = data->db_trans->get(data->db_trans, &key, &val, 0); + if(-1 == res) + { + data->last_error = ENGINE_INTERNAL_ERROR; + LOGS("Bookmark/%s->%s() Error while getting access to trans " + "database!", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + } + else if( 1 != res) + { + memcpy(&(data->freeID), val.data, sizeof(guint)); + //data->freeID = *((guint*)(val.data)); + LOGS("Bookmark/%s->%s() Available next free ID is equal = %d", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + data->freeID + ); + } + else + { + LOGS("Bookmark/%s->%s() Could not load the minimal, available" + " ID for next record - translation!", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + data->freeID = 1; + data->last_error = ENGINE_INTERNAL_ERROR; + } +} + + + +//============================================================================== +//============================================================================== +//============================================================================== +//-------------------------------------- FUNCTION FROM API 0.2 !!! +//============================================================================== + +gboolean bm_engine_add_word(Engine* engine, + gchar* word, + gchar* translation) { + LOGS("Bookmark/%s->%s() called. Param\nEngine at address: %p\n" + "word: %s\ntranslation address: %p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine, + word, + translation + ); + g_assert(engine != NULL); + g_assert(word != NULL); + g_assert(translation != NULL); + + // start bm_timer for this function + bm_timer(TIMER_START, (gchar*)(gchar*)__FUNCTION__); + + gboolean result = TRUE; + BookData* data = (BookData*)(engine->engine_data); + guint length = strlen(word) + 1; + DBT key = { word , length }; + DBT val = { NULL , 0 }; + + + gint db_res = data->db_words->get(data->db_words, &key, &val, 0); + if ( 0 == db_res ) + { + // there is already entry for this key - check if this translation is in + // database - check string hash equality + LOGS("Bookmark/%s->%s() updating entry for key: %s", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (gchar*)(key.data) + ); + + guint hash = g_str_hash(translation); + guint* values = (guint*)(val.data); + guint N = values[0]; + memcpy(&N, values, sizeof(guint)); + guint i = N; + guint tmp_hash = 0; + gboolean exist = FALSE; + ++values; + while(i--) + { + memcpy(&tmp_hash, values + (i*2+1), sizeof(guint)); + if( tmp_hash == hash) + { + exist = TRUE; + break; + } + } + if(!exist) + { + LOGS("Bookmark/%s->%s() Adding new translation to " + "already exist word in dictionary.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + values = (guint*)(val.data); + guint* tmp = eg_malloc(val.size + sizeof(guint)*2); + g_memmove(tmp, values, val.size); + tmp[0]++; + tmp[N*2+1] = data->freeID; + tmp[N*2+2] = hash; + val.data = tmp; + val.size += 2*sizeof(guint); + gint o = data->db_words->del(data->db_words,&key,0); + if(0 != o) + { + LOGS("Bookmark/%s->%s() Error while removing!", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + } + o = data->db_words->sync(data->db_words, 0); + if(0 != o) { + LOGS("Error while 1st synchronizing file with data!\n"); + } + + o = data->db_words->put(data->db_words, + &key, + &val, + R_NOOVERWRITE); + if(0 != o) { + LOGS("Error while putting new info about word!\n"); + } + o = data->db_words->sync(data->db_words, 0); + if(0 != o) { + LOGS("Error while 2nd synchronizing file with data!\n"); + } + bm_add_only_translation(data,translation,data->freeID); + (data->freeID)++; + bm_save_freeID(data); + eg_free(tmp); + } + else + { + LOGS("Bookmark/%s->%s() This translation already exist!", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + } + } + else if ( 1 == db_res ) + { + // there is no such a key - word in database - create new entry + LOGS("Bookmark/%s->%s() adding new entry for key: %s", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (gchar*)(key.data) + ); + result = bm_add_new_entry(word,translation,data); + } + else { + // there was an error, while accessing to the database + LOGS("Bookmark/%s->%s() Error while trying to add new word: %s", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (gchar*)(key.data) + ); + data->last_error = ENGINE_COULDNT_READ; + result = FALSE; + } + + bm_timer(TIMER_STOP, (gchar*)(gchar*)__FUNCTION__); + return result; +} +//------------------------------------------------------------------------------ +static gboolean bm_add_only_translation(BookData* data, + gchar* translation, + guint id) +{ + DBT key = { &id , sizeof(id) }; + DBT val = { translation , strlen(translation) + 1 }; + gint res = data->db_trans->put(data->db_trans, + &key, + &val, + R_NOOVERWRITE); + if(-1 == res) { + LOGS("Error while adding only translation!\n"); + return FALSE; + } + res = data->db_trans->sync(data->db_trans, 0); + if(-1 == res) { + LOGS("Error while synchronizing file with data\n"); + return FALSE; + } + return TRUE; +} +//------------------------------------------------------------------------------ +static gboolean bm_add_new_entry(gchar* word,gchar* translation,BookData* data) +{ + guint hash = g_str_hash(translation); + gboolean result = TRUE; + + DBT new_key = { &(data->freeID) , sizeof(guint) }; + DBT new_val = { translation , strlen(translation) + 1}; + gint db_res = data->db_trans->put(data->db_trans, + &new_key, + &new_val, + R_NOOVERWRITE + ); + if(-1 == db_res) + { + data->last_error = ENGINE_COULDNT_WRITE; + result = FALSE; + } + else + { + new_key.data = word; + new_key.size = strlen(word) + 1; + + // { number of entries , id of the first entry , hash #1 } + guint temp[3] = { 1 , data->freeID, hash }; + new_val.data = temp; + new_val.size = sizeof(guint) * 3; + + db_res = data->db_words->put(data->db_words, + &new_key, + &new_val, + R_NOOVERWRITE + ); + if(-1 == db_res) + { + new_key.data = &(data->freeID); + new_key.size = sizeof(guint); + data->db_trans->del(data->db_trans, &new_key, 0); + result = FALSE; + data->last_error = ENGINE_INTERNAL_ERROR; + } + else + { + result = TRUE; + (data->freeID)++; + bm_save_freeID(data); + } + } + db_res = data->db_words->sync(data->db_words,0); + db_res |= data->db_trans->sync(data->db_trans,0); + if(0 == db_res) + { + LOGS("Bookmark/%s->%s() adding new bookmark successful.\n", + (gchar*)__FILE__,(gchar*)__FUNCTION__); + } + else + { + LOGS("Bookmark/%s->%s() adding new bookmark failed.\n", + (gchar*)__FILE__,(gchar*)__FUNCTION__); + } + return result; +} +//------------------------------------------------------------------------------ +gboolean bm_engine_remove_word(Engine* engine, + gchar* word) { + gboolean result = TRUE; + + LOGS("Bookmark/%s->%s() called. Param\nEngine at address: %p\n" + "word: %s\n",(gchar*)__FILE__,(gchar*)__FUNCTION__,engine,word); + g_assert(engine != NULL); + g_assert(word != NULL); + bm_timer(TIMER_START, (gchar*)(gchar*)__FUNCTION__); + + BookData* data = (BookData*)(engine->engine_data); + + DBT key = { word , strlen(word) + 1 }; + DBT val = { NULL , 0 }; + + gint db_res = data->db_words->get(data->db_words, &key, &val, 0); + if ( 0 == db_res ) + { + guint* t = (guint*)(val.data); + guint N = t[0]; + guint id = 0; + memcpy(&N, t, sizeof(guint)); + ++t; + guint i = 0; + key.size = sizeof(guint); + key.data = &id; + while( i < N ) { + memcpy(&id, t + i*2, sizeof(guint)); + db_res = data->db_trans->del(data->db_trans, &key, 0); + if(0 != db_res) { + LOGS("Error while removing translation # %u for word: %s",i+1,word); + } + ++i; + } + } + else if( -1 == db_res) { + LOGS("Bookmark/%s->%s() Error while removing word: %s!", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + word + ); + return FALSE; + } + else { + LOGS("Bookmark/%s->%s() Ther is no such a word!", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + return TRUE; + }; + + // all data from trnaslation database has been deleted - now delete + // record in words database. + + DBT key_del = { word , strlen(word) + 1 }; + db_res = data->db_words->del(data->db_words,&key_del,0); + if(-1 == db_res) + { + LOGS("Bookmark/%s->%s() Error while removing!\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + } + else if(1 == db_res) + { + LOGS("Bookmark/%s->%s() There is no such a word!\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + } + else if(0 == db_res) + { + LOGS("Bookmark/%s->%s() word deleted successfully!\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + } + db_res = data->db_words->sync(data->db_words, 0); + + if((0 != db_res) || (NULL == data->db_words) || (NULL == data->db_trans)) { + LOGS("Error while 2nd synchronizing file with data!\n"); + } + + + bm_timer(TIMER_STOP, (gchar*)(gchar*)__FUNCTION__); + LOGS("Bookmark/%s->%s() finished work.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_get_lang_from(Engine* engine) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup("any"); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_get_lang_to(Engine* engine) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup("any"); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_get_title(Engine* engine) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strconcat(g_get_user_name(),"s' bookmarks",NULL); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_get_icon_path(Engine* engine) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup("/usr/share/pixmaps/ws_eng_bookmark_icon.png"); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} + +//============================================================================== +//============================================================================== +//============================================================================== +//-------------------------------------- FUNCTION TO WRITE (NOT IMPLEMENTED YET) +//============================================================================== + +//------------------------------------------------------------------------------ +// searching word by concrete engine +void bm_engine_search_word_translation(Engine* engine, + gchar* word, + gpointer cb_data) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM:engine at adress=%p\n" + "-->PARAM:word=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine, + word + ); + g_assert(engine != NULL); + g_assert(word != NULL); + // start bm_timer for this function + bm_timer(TIMER_START, (gchar*)(gchar*)__FUNCTION__); + BookData* data = (BookData*)(engine->engine_data); + + gchar* down_word = g_utf8_strdown(word,-1); + DBT search = { down_word , strlen(down_word) + 1 }; + DBT info = { NULL , 0 }; + DBT trans = { NULL , 0 }; + gchar* tran = NULL; + gchar* tran_ = NULL; + + gint tmp = data->db_words->get(data->db_words, &search, &info, 0); + if(0 == tmp) + { + // plugin found some information about this word + + guint* records = (guint*)(info.data); + guint count = records[0]; + memcpy(&count, records, sizeof(guint)); + //printf("Buffer (memcpy): %#x-%#x-%#x\n",count,records[1],records[2]); + ++records; + guint id = 0; + search.data = &id; + search.size = sizeof(guint); + + while(count-- > 0 && count < 100) + { + //printf("--> LOOP:count = %#x\n",count); + memcpy(search.data, records, sizeof(guint)); + records += 2; + tmp = data->db_trans->get(data->db_trans, &search, &trans, 0); + if(0 == tmp) + { + if(NULL == tran) + { + tran = g_strdup(trans.data); + } + else + { + tran_ = + g_strconcat(tran,"
",trans.data,NULL); + g_free(tran); + tran = tran_; + tran_ = NULL; + } + } + } + }; + g_free(down_word); + bm_timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + bm_timer(TIMER_START,"callback for returning word's translation START"); + // calling callback for word translation + + if ( NULL == cb_data ) + { + cb_data = data->cb_search_word_trans_data; + } + data->cb_search_word_trans(tran, word, cb_data, ENGINE_NO_ERROR); + + bm_timer(TIMER_STOP,"callback for returning word's translation END"); +// if(data->auto_free) { +// LOGS("Bookmark/%s->%s() deleting all dynamic data because " +// "AUTO_FREE=TRUE\n", +// (gchar*)__FILE__, +// (gchar*)__FUNCTION__ +// ); +// g_free(tran); +// } + g_free(tran); + tran = NULL; +} + +//------------------------------------------------------------------------------ +void bm_engine_close(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM: engine adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine); + g_assert(engine != NULL); + + BookData* data = (BookData*)(engine->engine_data); + data->db_words->close(data->db_words); + data->db_trans->close(data->db_trans); + + LOGS("Bookmark/%s->%s() engine at adress=%p is deleted.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine); + g_free(data->dict_path); + g_free(data); + data = NULL; + g_free(engine); + engine = NULL; +} +//------------------------------------------------------------------------------ + +Engine* bm_engine_create(gchar* location, + EngineOptimizationFlag auto_cache, + cb_progress progress_handler, + gpointer progress_data, + gdouble seed) +{ + LOGS("Bookmark/%s->%s() called.\n" + "-->PARAM:location=\'%s\'\n" + "-->PARAM:auto_cache=%d\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + location, + (guint)auto_cache + ); + bm_timer(TIMER_START,(gchar*)(gchar*)__FUNCTION__); + + gchar* tmp = g_strdup(location); + string_to_path(&tmp); + + Engine* result = (Engine*)g_try_malloc(sizeof(Engine)); + result->engine_location = bm_engine_location; + result->engine_is_optimized = bm_engine_is_optimized; + result->engine_optimize = bm_engine_optimize; + result->engine_search_word_list = bm_engine_search_word_list; + result->engine_search_word_translation = + bm_engine_search_word_translation; + result->engine_close = bm_engine_close; + result->engine_status = bm_engine_status; + result->engine_error_message = bm_engine_status_message; + result->engine_set_callback = bm_engine_set_callback; + result->engine_set_progress_seed = bm_engine_set_progress_seed; + result->engine_set_auto_free = bm_engine_set_auto_free; + // 0.2 API: + result->engine_add_word = bm_engine_add_word; + result->engine_remove_word = bm_engine_remove_word; + result->engine_get_lang_from = bm_engine_get_lang_from; + result->engine_get_lang_to = bm_engine_get_lang_to; + result->engine_get_title = bm_engine_get_title; + result->engine_get_icon_path = bm_engine_get_icon_path; + + + BookData* data = (BookData*)g_try_malloc(sizeof(BookData)); + result->engine_data = (gpointer)data; + + LOGS("Bookmark/%s->%s() opening file...\'%s\'.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + location + ); + + u_int32_t flags = O_CREAT | O_RDWR; + gchar* tmp_w = g_strconcat(tmp,"/bm_words.db",NULL); + gchar* tmp_t = g_strconcat(tmp,"/bm_trans.db",NULL); + + BTREEINFO inf = { + 0, /* permit duplicate keys? */ + 0, /* cache size; 0 - default size */ + 0, /* page size; 0 - default */ + 0, /* byte order; 0 - use host order */ + 0, /* min page number per page; 0 - default=2 */ + bm_compare_key_words, /* comparision function */ + NULL /* prefix comparision function */ + }; + data->info_words = inf; + inf.compare = bm_compare_key_trans; + data->info_trans = inf; + + data->db_words = + dbopen(tmp_w, /* On-disk file that holds the database. */ + flags, /* flags, like O_CREAT etc. */ + 0755, /* mode same as flags ? */ + DB_BTREE, /* type */ + &(data->info_words) + ); + if(data->db_words == NULL) + { + g_free(data); + g_free(result); + result = NULL; + } + else { + data->db_trans = + dbopen(tmp_t, + flags, + 0755, + DB_BTREE, + &(data->info_trans) + ); + + if(data->db_trans == NULL) + { + data->db_words->close(data->db_words); + g_free(data); + g_free(result); + result = NULL; + } + + } + g_free(tmp_w); tmp_w = NULL; + g_free(tmp_t); tmp_t = NULL; + if(result == NULL) { + LOGS("Bookmark/%s->%s() opening bookmark file failed.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + } + else { + LOGS("Bookmark/%s->%s()opening dictionary file successed.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + data->dict_path = g_strdup(tmp); + data->cb_progress_caching = progress_handler; + data->cb_progress_caching_data = progress_data; + data->cb_progress_caching_seed = seed; + data->cb_progress_word_list = NULL; + data->cb_progress_word_list_data = NULL; + data->cb_progress_word_list_seed = 0.01; + data->cb_progress_word_trans = NULL; + data->cb_progress_word_trans_data = NULL; + data->cb_progress_word_trans_seed = 0.01; + + data->cb_search_word_list = NULL; + data->cb_search_word_list_data = NULL; + + data->cb_search_word_trans = NULL; + data->cb_search_word_trans_data = NULL; + + data->auto_free = FALSE; + + bm_load_freeID(data); + + } + g_free(tmp); tmp = NULL; + + bm_timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + LOGS("Bookmark/%s->%s() returned Engine at adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ + + + +static gboolean is_Bookmark_db_file(gchar* file) { + LOGS("Bookmark/%s->%s() called.\n\ + -->PARAM:file=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + file + ); + + u_int32_t flags = O_RDWR; + DB* dbp = dbopen(file,flags,0755,DB_BTREE,NULL); + + if(NULL == dbp) + { + LOGS("Could no open! Wrong database! Not a bookmark.\n"); + return FALSE; + }; + + DBT search = {"four",sizeof("four")}; + DBT result = {NULL, 0}; + + int errCode = dbp->get(dbp,&search,&result,0); + dbp->close(dbp); + g_free(result.data); + + if(-1 == errCode) + { + LOGS("Could not read! Wrong database! Not a bookmark.\n"); + return FALSE; + }; + return TRUE; +} +//------------------------------------------------------------------------------ + + +void bm_engine_optimize(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called for engine at adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine + ); + LOGS("Unsupported optimization mechanizm for this engine!\n"); + LOGS("Bookmark/%s->%s()'s work finished.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); +} +//------------------------------------------------------------------------------ +gboolean bm_engine_check(gchar* location) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM:location=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + location + ); + bm_timer(TIMER_START,(gchar*)(gchar*)__FUNCTION__); + gboolean result = TRUE; + gchar* filepath = g_strdup(location); + gchar* tmp = NULL; + gchar* tmp2 = NULL; + + string_to_path(&filepath); + if (filepath == NULL) { + result = FALSE; + LOGS("Bookmark/%s->%s() location \'%s\' is not a proper " + "path!\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + location + ); + } + else { + tmp = g_strconcat(filepath,"/bm_words.db",NULL); + tmp2 = g_strconcat(filepath,"/bm_trans.db",NULL); + g_free(filepath); + filepath = tmp; + tmp = NULL; + + LOGS("Bookmark/%s->%s() finnal file to check is: %s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + filepath + ); + if (!g_file_test(filepath, G_FILE_TEST_IS_REGULAR) || + !g_file_test(tmp2, G_FILE_TEST_IS_REGULAR) + ) { + LOGS("Bookmark/%s->%s() file \'%s\' does not exists!\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + filepath + ); + result = FALSE; + }; + }; + if (result != FALSE) { + result = is_Bookmark_db_file(filepath) & + is_Bookmark_db_file(tmp2); + }; + + g_free(filepath); filepath = NULL; + g_free(tmp2); tmp2 = NULL; + bm_timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + LOGS("Bookmark/%s->%s() returned bool statement=%s.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + PRINT_STATE(result) + ); + return result; +} + +//------------------------------------------------------------------------------ +gboolean bm_engine_is_optimized(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM: engine adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine + ); + g_assert(engine != NULL); + gboolean result = FALSE; + LOGS("Bookmark/%s->%s() returned bool statement=%s.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + PRINT_STATE(result) + ); + return result; +} +//------------------------------------------------------------------------------ + +void bm_engine_search_word_list(Engine* engine, + gchar* pattern, + gpointer cb_data) +{ + LOGS("Bookmark/%s->%s() called. Searching words list\n" + "-->PARAM:engine at adress=%p\n" + "-->PARAM:pattern=\"%s\"\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine, + pattern + ); + g_assert(engine != NULL); + g_assert(pattern != NULL); + + bm_timer(TIMER_START,(gchar*)(gchar*)__FUNCTION__); + BookData* data = (BookData*)(engine->engine_data); + if(data->cb_search_word_list == NULL) { + LOGS("Bookmark/%s->%s() callback for Word List not set. " + "Searching aborted.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + bm_timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + return; + }; + + GArray* result = g_array_new(TRUE, TRUE, sizeof(gchar*) ); + guint a = G_MAXUINT32; + DBT search = { &a , sizeof(a) }; + DBT reply = { NULL , 0 }; + gchar* down_word = NULL; + gchar *tmp; + + GPatternSpec* regex; + regex = g_pattern_spec_new (g_utf8_casefold(pattern,-1)); + + gint code = data->db_words->sync(data->db_words, 0); + code = data->db_words->seq(data->db_words, &search, &reply, R_FIRST); + +/* + if((('*' == pattern[0]) && ('\0' == pattern[1])) || ('\0' == pattern[0])) + { + // especiall treat if user give only '*' + while(0 == code) { + gchar* cos = g_strdup(search.data); + g_array_append_val(result,cos); + code = data->db_words->seq(data->db_words, &search, &reply, R_NEXT); + // we are giving to the user all words from dictionary + } + } + else + {*/ + while(0 == code) { + down_word = g_utf8_casefold((gchar*)(search.data),-1); + + if( 0 == g_pattern_match_string( regex, down_word ) ) + { + tmp = g_strdup(search.data); + g_array_append_val(result, tmp ); + }; + + //eg_free(reply.data); + eg_free(down_word); + code = data->db_words->seq(data->db_words, &search, &reply, R_NEXT); + } + + bm_timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + g_pattern_spec_free (regex); + + + bm_timer(TIMER_START,"callback for returning words LIST START"); + // calling callback for word translation + + if ( NULL == cb_data ) + { + cb_data = data->cb_search_word_list_data; + } + data->cb_search_word_list(result, pattern, cb_data, ENGINE_NO_ERROR); + + + /* if(data->auto_free) { + LOGS("Bookmark/%s->%s() deleting all dynamic data because " + "AUTO_FREE=TRUE\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + len = 0; + while(NULL != (tmp = g_array_index(result,gchar*,len++))) + { + g_free(tmp); tmp = NULL; + } + g_array_free(result, TRUE); + }*/ + guint len = 0; + + while(NULL != (tmp = g_array_index(result,gchar*,len++))) + { + g_free(tmp); tmp = NULL; + } + g_array_free(result, TRUE); + bm_timer(TIMER_STOP,"callback for returning word LIST END"); +} + +//============================================================================== +//============================================================================== +//============================================================================== +//---------------------------------------------------------- COMPLETED FUNCTIONS +//============================================================================== +// global functions +EngineModule engine_global_functions() +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + EngineModule result; + result.engine_check = bm_engine_check; + result.engine_description = bm_engine_description; + result.engine_format = bm_engine_format; + result.engine_version = bm_engine_version; + result.engine_create = bm_engine_create; + LOGS("Bookmark/%s->%s()returned EngineModule at adress=%p.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + &result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_status_message(error) +gchar* bm_engine_status_message(EngineStatus error) +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + switch (error) { + case ENGINE_NO_ERROR: + return "No error."; + case ENGINE_WRONG_FILE: + return "File which You are trying to use is wrong type."; + case ENGINE_COULDNT_READ: + return "Could not read from file."; + case ENGINE_NO_FILE: + return "There is no such a file."; + case ENGINE_OUT_OF_MEMORY: + return "There were no enough memory for this action."; + default: + return "Wrong engine's status identifier!"; + } +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_module_get_version(module) +gchar* bm_engine_version() +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_VERSION); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_module_get_format(module) +gchar* bm_engine_format() +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_FORMAT); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_module_get_description(module) +gchar* bm_engine_description() +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_DESCRIPTION); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_get_location(engine) +gchar* bm_engine_location(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM: engine adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine + ); + g_assert(engine != NULL); + BookData* data = (BookData*)(engine->engine_data); + + gchar* result; + if(data->auto_free) { + result = data->dict_path; + } + else { + result = g_strdup(data->dict_path); + } + + LOGS("Bookmark/%s->%s() returned string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_set_auto_free(engine, state) +void bm_engine_set_auto_free(Engine* engine, gboolean state) +{ + LOGS("Bookmark/%s->%s() called.\n" + "-->PARAM:engine at adress=%p\n" + "-->PARAM:state=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine, + PRINT_STATE(state) + ); + g_assert(engine != NULL); + BookData* data = (BookData*)(engine->engine_data); + + data->auto_free = state; + LOGS("Bookmark/%s->%s() Current auto_free is %s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + PRINT_STATE(data->auto_free) + ); +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_get_last_status(engine) +EngineStatus bm_engine_status(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called.\n" + "-->PARAM:engine at adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine + ); + BookData* data = (BookData*)(engine->engine_data); + LOGS("Bookmark/%s->%s() returned error code: %d\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (gint)(data->last_error) + ); + return data->last_error; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_set_progress_seed(engine, signal, val) +void bm_engine_set_progress_seed(Engine* engine, gchar* signal, gdouble seed) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + BookData* data = (BookData*)(engine->engine_data); + if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) { + data->cb_progress_caching_seed = seed; + LOGS("Bookmark/%s->%s() sets new seed=%0.2f for for signal " + "\"%s\".\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + seed, + signal + ); + } + else { + LOGS("Bookmark/%s->%s() unsupported signalfor progress: %s.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + }; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_set_callback(engine,signal,c_handler,data) +gpointer bm_engine_set_callback(Engine* engine, + gchar* signal, + gpointer c_handler, + gpointer user_data) +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + g_assert(engine != NULL); + g_assert(signal != NULL); + g_assert(c_handler != NULL); + BookData* data = (BookData*)(engine->engine_data); + if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) { + gpointer result = data->cb_progress_caching; + data->cb_progress_caching = c_handler; + data->cb_progress_caching_data = user_data; + LOGS("Bookmark/%s->%s() sets handler for signal \"%s\".\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + LOGS("Bookmark/%s->%s() Function at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)c_handler + ); + LOGS("Bookmark/%s->%s() Data at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)user_data + ); + return result; + } + else if(g_ascii_strcasecmp(signal, ENGINE_WORD_LIST_SIGNAL) == 0) { + gpointer result = data->cb_search_word_list; + data->cb_search_word_list = c_handler; + data->cb_search_word_list_data = user_data; + LOGS("Bookmark/%s->%s() sets handler for signal \"%s\".\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + LOGS("Bookmark/%s->%s() Function at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)c_handler + ); + LOGS("Bookmark/%s->%s() Data at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)user_data + ); + return result; + } + else if(g_ascii_strcasecmp(signal, + ENGINE_WORD_TRANSLATION_SIGNAL) == 0) { + gpointer result = data->cb_search_word_trans; + data->cb_search_word_trans = c_handler; + data->cb_search_word_trans_data = user_data; + LOGS("Bookmark/%s->%s() sets handler for signal \"%s\".\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + LOGS("Bookmark/%s->%s() Function at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)c_handler + ); + LOGS("Bookmark/%s->%s() Data at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)user_data + ); + return result; + } + else { + g_warning("Bookmark/%s->%s() unsupported signal: %s.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + return NULL; + } +} + + +//============================================================================== +//============================================================================== +//============================================================================== +//---------------------------------------------------------- HELPFULLY FUNCTIONS +//============================================================================== + +//------------------------------------------------------------------------------ +static gchar* string_to_path(gchar** string) { + LOGS("Bookmark/%s->%s() called.\n\ + -->PARAM:string=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + string[0] + ); + gchar* arg = string[0]; + gchar* new = NULL; + // cleaning from leading and trailing whitespaces + g_strstrip(arg); + // add current directory if this is not absolute directory + if (!g_path_is_absolute(arg)) { + gchar* tmp = g_get_current_dir(); + new = g_strconcat(tmp,"/",arg,NULL); + g_free(arg); arg = new; new = NULL; + }; + // this is not a directory + if (!g_file_test(arg, G_FILE_TEST_IS_DIR)) { + // if this is wrong filepath, string was wrong + if (!g_file_test(arg, G_FILE_TEST_IS_REGULAR)) { + g_free(arg); + new = NULL; + } + //if this is a file, remove filename + else + { + new = g_path_get_dirname (arg); + g_free(arg); + } + } + // this is a directory + else { + // remove suffix "/" if neded... + if (g_str_has_suffix(arg,"/") ) { + new = g_path_get_dirname (arg); + g_free(arg); + } + else { + new = arg; + } + }; + // now in new should be proper filepath, if not, string was wrong + if (!g_file_test(new, G_FILE_TEST_IS_DIR)) { + // if that directory does not exist, passed string wasn't proper + g_free(new); + new = NULL; + }; + // replace string under passed address + string[0] = new; + LOGS("Bookmark/%s->%s() returned string=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + string[0] + ); + return new; +} +//------------------------------------------------------------------------------ +static double bm_timer(gboolean start, gchar* message) +{ + static GArray* stack = NULL; + static gboolean first_run = TRUE; + static struct timeval actual_time; + static struct timeval last_time; + static struct timeval result; + static double seconds = 0.0; + if(first_run) { + first_run = FALSE; + stack = g_array_new(TRUE, TRUE, sizeof(struct timeval)); + }; + + if (start) { + LOGS("Bookmark->%s() start bm_timer for function '%s()'.\n", + (gchar*)__FUNCTION__, + message + ); + g_array_prepend_val(stack, actual_time); + gettimeofday(&g_array_index(stack, struct timeval, 0),NULL); + return -1.0; + } + // we just want to end some bm_timer - print some information about + // working time; + else { + gettimeofday(&actual_time,NULL); + last_time = g_array_index(stack, struct timeval, 0); + g_array_remove_index(stack, 0); + + if (actual_time.tv_usec < last_time.tv_usec) { + int nsec = (last_time.tv_usec - actual_time.tv_usec) / + (1000000 + 1); + last_time.tv_usec -= 1000000 * nsec; + last_time.tv_sec += nsec; + } + if (actual_time.tv_usec - last_time.tv_usec > 1000000) { + int nsec = (last_time.tv_usec - actual_time.tv_usec) / + 1000000; + last_time.tv_usec += 1000000 * nsec; + last_time.tv_sec -= nsec; + } + result.tv_sec = actual_time.tv_sec - last_time.tv_sec; + result.tv_usec = actual_time.tv_usec - last_time.tv_usec; + seconds = (((double)(result.tv_usec)) / 1e6) + + ((double)(result.tv_sec)); + + LOGS("Bookmark->%s() function \'%s()\' was working for: %g " + "[s] or %ld [us].\n", + (gchar*)__FUNCTION__, + message, + seconds, + ((long)(result.tv_sec*1e6)+(result.tv_usec)) + ); + // stack is empty so we delete everything + if(stack->len == 0) + { + g_array_free(stack, TRUE); + first_run = TRUE; + } + } + return seconds; +} +//------------------------------------------------------------------------------ diff --git a/src/bookmarks/bdb/src/test.c b/src/bookmarks/bdb/src/test.c new file mode 100755 index 0000000..7ca80f3 --- /dev/null +++ b/src/bookmarks/bdb/src/test.c @@ -0,0 +1,160 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#include +#include +#include +#include + + +getting_additional get_functions; // additinal functions for concrete module (e.g. XDXF) + +void print_list(GArray* list, gchar* pattern, gpointer user_data, EngineStatus error) { + printf((gchar*)user_data,pattern); + int i = 0; + while(g_array_index(list, gchar*, i) != NULL) + { + printf(" %d. : %s\n",i+1,g_array_index(list, gchar*, i)); + i++; + } + printf("--------------------------------------------------\n"); +} + +void print_translation(gchar* translation, gchar* word, gpointer user_data, EngineStatus error) { + printf((gchar*)user_data,word); + printf("%s\nTRANSLATION ENDS.\n",translation); +} + +void caching_progress(gdouble value, gpointer user_data, EngineStatus error) { + printf((gchar*)user_data,value); +} + +int main(int argc, char** argv) +{ + char* nameApp = "BerkeleyDB Bookmark Engine test: "; + printf("%sStarting test program of module: dictionary_engine.\n",nameApp); + + + gchar* current_directory = g_get_current_dir(); + printf("%sCurrent directory: %s\n",nameApp,current_directory); + gchar* library_to_path = g_strconcat(current_directory, "/ws_bookmark.so", NULL); + printf("%sEngine library should be in location:\n\t%s\n",nameApp,library_to_path); + + GModule *library = g_module_open(library_to_path, G_MODULE_BIND_LAZY); + if(!library) { + printf("%sLoading module failed. \nReason: %s\n",nameApp,g_module_error()); + return 1; + }; + + //dict_eng_module_get_global_functions(library,get_functions); + g_module_symbol ( (library),_GLOBAL_FUNCTIONS_NAME_, (gpointer)&get_functions); + if(get_functions == NULL) { + printf("%sLoading function failed\n",nameApp); + return 2; + } + else printf("%sLoading function OK\n",nameApp); + + EngineModule module = get_functions(); + gchar* desc = dict_eng_module_get_description(module); + g_free(desc); + printf("Module description: %s\n",desc); + Engine* bm; + + gboolean is_compatible = dict_eng_module_check(module,"/home/lukasz/MyDocs/release/mdictionary/trunk/src/bookmarks/bdb/data"); + if(is_compatible == TRUE) + { + printf("Location is compatible with enigne!\n"); + } + else { + printf("Location is not compatible with enigne!\n"); + return 1; + } + + bm = dict_eng_module_create(module, + "/home/lukasz/MyDocs/release/mdictionary/trunk/src/bookmarks/bdb/data" , + ENGINE_CREATE); + gchar* location = dict_eng_get_location(bm); + printf("Lokalizacja: %s\n",location); + g_free(location); + dict_eng_set_callback(bm, + ENGINE_WORD_LIST_SIGNAL, + print_list, + "Word list matches to pattern: %s\n" + ); + dict_eng_set_callback(bm, + ENGINE_WORD_TRANSLATION_SIGNAL , + print_translation, + "Translation for word: \'%s\':\n"); + + dict_eng_add_word(bm, "stranger", "translation number 1"); + dict_eng_add_word(bm, "stranger", "translation number 2"); + dict_eng_add_word(bm, "stranger", "translation number 3"); + dict_eng_add_word(bm, "str", "translation number 1 shorter"); + dict_eng_add_word(bm, "gandzia", "rulez forever!"); + dict_eng_search_word_list(bm,"*"); + + //dict_eng_remove_word(bm, "stranger"); + //dict_eng_search_word_list(bm,"*"); + + dict_eng_search_word_translation(bm,"stranger"); + + //dict_eng_remove_word(bm, "stranger"); + //dict_eng_add_word(bm, "stranger", "author of the plugin you are using now!"); + //dict_eng_add_word(bm, "stranger", "author of the plugin you are using now!"); + //dict_eng_add_word(bm, "stranger", "He knows gandzia."); + //dict_eng_add_word(bm, "stranger", "He knows gandzia. 2 "); + //dict_eng_add_word(bm, "stranger", "He knows gandzia. 3"); + //dict_eng_destroy(bm); + //dict_eng_add_word(bm, "gandzia", "super girl!"); + //dict_eng_add_word(bm, "stranger", "He knows gandzia."); + //dict_eng_search_word_list(bm,"*"); + //dict_eng_search_word_list(bm,"f"); + //dict_eng_search_word_list(bm,"s"); + //dict_eng_search_word_translation(sd,"1 word"); + //dict_eng_destroy(bm); + //return 0; + + + + dict_eng_remove_word(bm, "stranger"); + dict_eng_remove_word(bm, "gandzia"); + dict_eng_remove_word(bm, "lukas"); + dict_eng_add_word(bm, "stranger", "autor pluginu tego wlasnie to jest!"); + dict_eng_add_word(bm, "gandzia", "rulez"); + dict_eng_add_word(bm, "lukas", "pawlik"); + dict_eng_remove_word(bm, "stranger"); + + dict_eng_search_word_translation(bm,"stranger"); + + dict_eng_add_word(bm, "stranger", "autor pluginu tego wlasnie to jest!"); + dict_eng_search_word_translation(bm,"stranger"); + dict_eng_search_word_list(bm,"gandzia"); + +// printf("Lang FROM:%s\n",dict_eng_get_lang_from(bm)); +// printf(" Lang TO:%s\n",dict_eng_get_lang_to(bm)); +// printf(" Title:%s\n",dict_eng_get_title(bm)); +// printf("Icon path:%s\n",dict_eng_get_icon_path(bm)); + + dict_eng_destroy(bm); + g_free(current_directory); + g_free(library_to_path); + printf("%sClosed.\n",nameApp); + return 0; +} + diff --git a/src/bookmarks/bdb/src/testMakeDatabase.c b/src/bookmarks/bdb/src/testMakeDatabase.c new file mode 100755 index 0000000..7ca65e1 --- /dev/null +++ b/src/bookmarks/bdb/src/testMakeDatabase.c @@ -0,0 +1,135 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ + +#include +#include +#include + +const guint records_number = 1000; + +// ---------------------------------------------------------------------------------- +sqlite* database_make(gchar* path) { + gchar* buffer = NULL; + sqlite* result = NULL; + // creatingh database + result = sqlite_open(path, + 0600, + &buffer); + // check if everything was okey + if(!result) { + g_printf("Error while trying to create database:\n%s\n",buffer); + g_free(buffer); buffer = NULL; + return NULL; + }; + // return pointer to database + return result; +} +// ---------------------------------------------------------------------------------- +gint database_add_test_table(sqlite* db) { + gint result = 0; + //gchar sql[] = "CREATE TABLE words(id INTEGER PRIMARY KEY, word TEXT UNIQUE);"; + gchar sql2[] = "CREATE TABLE translations(id INTEGER PRIMARY KEY, word TEXT, translation TEXT);"; + gchar* err = NULL; +/* + result = sqlite_exec(db, sql, NULL, NULL, &err); + if(err || result!=0) { + g_printf("Error while creating \'words\' table:\n%s\n",err); + return 1; + } +*/ + result = sqlite_exec(db, sql2, NULL, NULL, &err); + if(err || result!=0) { + g_printf("Error while creating \'translations\' table:\n%s\n",err); + return 2; + } + + return result; +} +// ---------------------------------------------------------------------------------- +gint database_add_test_record(sqlite* db, guint i) { + gint result = 0; + gchar* sql = NULL; + gchar* err = NULL; + gint last_id = 0; + gint word_count = 1; + gchar buffer[] = " "; + gchar last_char[] = " "; + gchar tran[] = "this is a translation number 10.000 for word 10.000 word <-----"; + g_sprintf(buffer,"%d word",i); +/* + sql = g_strconcat("INSERT INTO words VALUES(NULL,\'",buffer,"\');", NULL); + result = sqlite_exec(db, sql, NULL, NULL, &err); + if(err || result!=0) { + g_printf("Error while trying to add new word %d:\n%s\n",i,err); + g_free(sql); + return 1; + } + g_free(sql); + last_id = sqlite_last_insert_rowid(db); + g_sprintf(last_char,"%d",last_id); +*/ + if(i == 5000) { + word_count = 5; + g_printf("Adding more records for word - test\n"); + } + gint j; + for(j=0; j + Copyright (C) + + 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. + +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. + + , 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 Lesser General +Public License instead of this License. \ No newline at end of file diff --git a/src/bookmarks/sql/Makefile b/src/bookmarks/sql/Makefile new file mode 100644 index 0000000..56bf4ff --- /dev/null +++ b/src/bookmarks/sql/Makefile @@ -0,0 +1,48 @@ +COMPILER = gcc +DEBUG = -Wall -g +SOURCES = ./src +INCLUDE = include +INCLUDE_ENGINE = ../../../include +LIBS = `pkg-config --libs glib-2.0 gmodule-2.0` -lsqlite +FLAGS = `pkg-config --cflags glib-2.0 gmodule-2.0` -I${INCLUDE} -I${INCLUDE_ENGINE} ${DEBUG} +BINARIES = bin +FINAL = ../../../bin/ws_bookmark.so + + +${FINAL}: ${BINARIES}/bookmark.o ${SOURCES}/engine_bookmark.c + @gcc -shared -fPIC ${FLAGS} ${LIBS} ${BINARIES}/bookmark.o -o ${FINAL} + +${BINARIES}/bookmark.o: ${SOURCES}/engine_bookmark.c + @gcc -c -fPIC -o ${BINARIES}/bookmark.o ${SOURCES}/engine_bookmark.c ${FLAGS} + +clean: + @-rm -f ${BINARIES}/* + @-rm -f ${FINAL} + @echo -e -n "Project's 'BookmarkEngine' directories has been cleaned.\n" + +cleandata: + @-rm -f ws_bookmarks-journal + @-rm -f ws_bookmarks + + +data: ${SOURCES}/testMakeDatabase.c + @echo -e -n "Compiling testDatabase...\n" + @gcc -o ${SOURCES}/testDatabase ${SOURCES}/testMakeDatabase.c ${FLAGS} ${LIBS} + +datarun: data + @run-standalone.sh src/testDatabase + +test: test.o + @echo "Linking test program..." + @gcc ${LIBS} ${DEBUG} -o ${SOURCES}/test ${BINARIES}/test.o + @echo -e "Building test program finished.\n" + +test.o: + @echo "Compiling test program..." + @gcc ${FLAGS} ${DEBUG} -c -o ${BINARIES}/test.o ${SOURCES}/test.c + +check: + @echo "Running test program:" + @run-standalone.sh ${SOURCES}/test + + \ No newline at end of file diff --git a/src/bookmarks/sql/include/engine_bookmark.h b/src/bookmarks/sql/include/engine_bookmark.h new file mode 100644 index 0000000..5884cb1 --- /dev/null +++ b/src/bookmarks/sql/include/engine_bookmark.h @@ -0,0 +1,210 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#ifndef _DICTIONARY_ENGINE_BOOKMARK +#define _DICTIONARY_ENGINE_BOOKMARK + +#ifdef __cplusplus + extern "C" { +#endif + +//______________________________________________________________________________ +// ***************************************************************************** +//************************************************************* HEADERS SECTION: +//------------------------------------------------------------------------------ +// headers with unix types/functions - only for timers +#include +#include +#include +#include +#include +//------------------------------------------------------------------------------ +// header with GLIB definitions/functions/types +#include +//------------------------------------------------------------------------------ +// header wit engine API +#include +//------------------------------------------------------------------------------ +// header wit sqlite 2.x API +#include +//------------------------------------------------------------------------------ + +//______________________________________________________________________________ +// ***************************************************************************** +//********************************************************* DEFINITIONS SECTION: +//------------------------------------------------------------------------------ +// definitions for timer function - flag telling if we want to start or stop +// timing +#define TIMER_START TRUE +#define TIMER_STOP FALSE +//------------------------------------------------------------------------------ +// definitions of version and format which engine handles +static const gchar* DIC_ENG_VERSION = "0.1"; +static const gchar* DIC_ENG_FORMAT = "Users' Bookmarks"; +static const gchar* DIC_ENG_DESCRIPTION = "This module handles users' bookmarks."; + +//------------------------------------------------------------------------------ +// macro for "printing" gboolean statement - "TRUE" or "FALSE" +#define PRINT_STATE(state) ( (state) ? "TRUE" : "FALSE" ) +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//****************************************** DATA STRUCTURE DEFINITIONS SECTION: +//------------------------------------------------------------------------------ +/** \brief Internal data structure of XDXF Engine. + */ +struct _BookData { + sqlite* db; + + gchar* dict_path; + EngineStatus last_error; + gboolean auto_free; + + cb_progress cb_progress_caching; + gpointer cb_progress_caching_data; + gdouble cb_progress_caching_seed; + + cb_progress cb_progress_word_list; + gpointer cb_progress_word_list_data; + gdouble cb_progress_word_list_seed; + + cb_progress cb_progress_word_trans; + gpointer cb_progress_word_trans_data; + gdouble cb_progress_word_trans_seed; + + cb_word_list cb_search_word_list; + gpointer cb_search_word_list_data; + + cb_word_translation cb_search_word_trans; + gpointer cb_search_word_trans_data; +}; +typedef struct _BookData BookData; +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//************************************************ ADDITIONAL FUNCTIONS SECTION: +//------------------------------------------------------------------------------ +// returning concrete part of file +//static gchar* read_file_part(FilePart* part, GnomeVFSHandle* file); +//------------------------------------------------------------------------------ +// convert string to proper path name (no filename, no "/" at the ned, file +// exist) +static gchar* string_to_path(gchar** string); +//------------------------------------------------------------------------------ +// tells if file is in XDXF format (file should exist) +//static gboolean is_xdxf_file(gchar* file); +//------------------------------------------------------------------------------ +// start/stop timers - returnet -1.0 if we start or seconds passed from start +// if we want to stop timer +static double timer(gboolean start, gchar* message); +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//****************************************************** MAIN FUNCTIONS SECTION: +//------------------------------------------------------------------------------ +gboolean bm_engine_add_word(Engine* engine, + gchar* word, + gchar* translation); +//------------------------------------------------------------------------------ +gboolean bm_engine_remove_word(Engine* engine, + gchar* word); +//------------------------------------------------------------------------------ +gchar* bm_engine_get_lang_from(Engine* engine); +//------------------------------------------------------------------------------ +gchar* bm_engine_get_lang_to(Engine* engine); +//------------------------------------------------------------------------------ +gchar* bm_engine_get_title(Engine* engine); +//------------------------------------------------------------------------------ +gchar* bm_engine_get_icon_path(Engine* engine); + + + +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_check(module,location) function +gboolean bm_engine_check(gchar* location); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_get_description(module) function +gchar* bm_engine_description(); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_get_format(module) function +gchar* bm_engine_format(); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_get_version(module) function +gchar* bm_engine_version(); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_create(module,location,flags) and +// dict_eng_module_create_ext(module,location,flags) functions +Engine* bm_engine_create(gchar* location, + EngineOptimizationFlag flags, + cb_progress progress_handler, + gpointer progress_data, + gdouble seed); +//------------------------------------------------------------------------------ +// implementation of dict_eng_destroy(engine) function +void bm_engine_close(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_get_location(engine) function +gchar* bm_engine_location(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_optimize(engine) function +void bm_engine_optimize(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_is_optimized( engine ) function +gboolean bm_engine_is_optimized(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_set_auto_free(engine, state) function +void bm_engine_set_auto_free(Engine* engine, gboolean state); +//------------------------------------------------------------------------------ +// implementation of dict_eng_set_callback(engine,signal,c_handler,data) +// function +gpointer bm_engine_set_callback(Engine* engine, + gchar* event, + gpointer c_handler, + gpointer user_data); +//------------------------------------------------------------------------------ +// implementation of dict_eng_set_progress_seed(engine, signal, val) function +void bm_engine_set_progress_seed(Engine* engine, + gchar* signal, + gdouble seed); +//------------------------------------------------------------------------------ +// implementation ofdict_eng_search_word_list(engine,pattern) function +void bm_engine_search_word_list(Engine* engine, gchar* pattern); +//------------------------------------------------------------------------------ +// implementation of dict_eng_search_word_translation(engine,word) function +void bm_engine_search_word_translation(Engine* engine, gchar* word); +//------------------------------------------------------------------------------ +// implementation of dict_eng_get_last_state(engine) function +EngineStatus bm_engine_status(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_state_message(error) function +gchar* bm_engine_status_message(EngineStatus error); +//------------------------------------------------------------------------------ +// implementation of engine_global_functions(void) function +EngineModule engine_global_functions(); + +#ifdef __cplusplus +} +#endif +#endif /* #ifndef _DICTIONARY_ENGINE_STARDICT */ diff --git a/src/bookmarks/sql/src/engine_bookmark.c b/src/bookmarks/sql/src/engine_bookmark.c new file mode 100644 index 0000000..05abb86 --- /dev/null +++ b/src/bookmarks/sql/src/engine_bookmark.c @@ -0,0 +1,1055 @@ +/****************************************************************************** +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +******************************************************************************/ + +// header with data structure and function definition for XDXF engine. +// Also Engine API. +#include +//------------------------------------------------------------------------------ + +#ifndef NOLOGS +#include +#include +#include +#endif + +#define LOGS g_debug + +/*inline void LOGS(gchar* frm, ...) { +#ifndef NOLOGS + //g_printf(frm); +#endif +}*/ + +//============================================================================== +//============================================================================== +//============================================================================== +//-------------------------------------- FUNCTION FROM API 0.2 !!! +//============================================================================== +int get_id(void* data,int n,char** argv,char** names) { + int len = strlen(&(argv[0][0])); + memcpy(data,&(argv[0][0]), len); + gchar* tmp = (gchar*)data; + tmp[len] = 0; + return 0; +} + +gboolean bm_engine_add_word(Engine* engine, + gchar* word, + gchar* translation) { + gint sql_res = 0; + gchar* err = NULL; + gboolean result = TRUE; + gchar* sql = NULL; + + LOGS("Bookmark/%s->%s() called. Param\nEngine at address: %p\n" + "word: %s\ntranslation address: %p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine, + word, + translation + ); + g_assert(engine != NULL); + g_assert(word != NULL); + g_assert(translation != NULL); + + // start timer for this function + timer(TIMER_START, (gchar*)(gchar*)__FUNCTION__); + + BookData* data = (BookData*)(engine->engine_data); +/* + + gchar* tmp = g_utf8_strdown(word,-1); + sql = g_strconcat("INSERT INTO words VALUES(NULL,\'",tmp,"\');",NULL); + sql_res = sqlite_exec(data->db, sql, NULL, NULL, &err); + if(err || sql_res!=0) { + LOGS("This word exists already\nError description: %s\n",err); + } + g_free(sql); sql = NULL; + const gchar* end; + sqlite_vm* query = NULL; + + sql = g_strconcat("SELECT id FROM words WHERE word=\'",tmp,"\'",NULL); + gchar word_id[20]; + sqlite_exec( + (data->db), + sql, + get_id, + word_id, + &err + ); + LOGS("Founded id is equal: %s\n",word_id); +*/ + //sql = g_strconcat("INSERT INTO translations VALUES(NULL,\'",word,"\',\'",translation,"\');",NULL); + sql = sqlite_mprintf("INSERT INTO translations VALUES(NULL,\'%q\',\'%q\');", word, translation); + + sql_res = sqlite_exec(data->db, sql, NULL, NULL, &err); + if(err || sql_res!=0) { + LOGS("Error while adding translation for word %s\n" + "Reason: %s", + word, + err + ); + result = FALSE; + } + g_free(sql); sql = NULL; + + timer(TIMER_STOP, (gchar*)(gchar*)__FUNCTION__); + return result; +} +//------------------------------------------------------------------------------ +gboolean bm_engine_remove_word(Engine* engine, gchar* word) { + gint sql_res = 0; + gchar* err = NULL; + gboolean result = TRUE; + + LOGS("Bookmark/%s->%s() called. Param\nEngine at address: %p\n" + "word: %s\n",(gchar*)__FILE__,(gchar*)__FUNCTION__,engine,word); + g_assert(engine != NULL); + g_assert(word != NULL); + timer(TIMER_START, (gchar*)(gchar*)__FUNCTION__); + + BookData* data = (BookData*)(engine->engine_data); +/* + gchar* tmp = g_utf8_strdown(word,-1); + gchar* sql = g_strconcat("DELETE FROM translations WHERE word_id = " + "(SELECT id FROM words WHERE word=\'", + tmp, + "\');", + NULL + ); + g_free(tmp); tmp = NULL; + sql_res = sqlite_exec(data->db, sql, NULL, NULL, &err); + if(err || sql_res!=0) { + LOGS("Error while deleting \'%s\' word translation(s):\n%s\n",word,err); + g_free(sql); sql = NULL; + return FALSE; + } + g_free(sql); sql = NULL; + + gchar* sql = g_strconcat("DELETE FROM translations WHERE word LIKE \'", + word, + "\';", + NULL + ); +*/ + gchar* sql = sqlite_mprintf("DELETE FROM translations WHERE word LIKE " + "\'%q\';", word); + sql_res = sqlite_exec(data->db, sql, NULL, NULL, &err); + if(err || sql_res!=0) { + LOGS("Error while deleting \'%s\' <-> reason:\n%s\n",word,err); + g_free(sql); sql = NULL; + return FALSE; + } + g_free(sql); sql = NULL; + + timer(TIMER_STOP, (gchar*)(gchar*)__FUNCTION__); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_get_lang_from(Engine* engine) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup("any"); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_get_lang_to(Engine* engine) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup("any"); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_get_title(Engine* engine) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strconcat(g_get_user_name(),"s' bookmarks",NULL); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_get_icon_path(Engine* engine) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup("/usr/share/pixmaps/ws_eng_bookmark_icon.png"); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} + +//============================================================================== +//============================================================================== +//============================================================================== +//-------------------------------------- FUNCTION TO WRITE (NOT IMPLEMENTED YET) +//============================================================================== + +//------------------------------------------------------------------------------ +// searching word by concrete engine +void bm_engine_search_word_translation(Engine* engine, gchar* word) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM:engine at adress=%p\n" + "-->PARAM:word=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine, + word + ); + g_assert(engine != NULL); + g_assert(word != NULL); + // start timer for this function + timer(TIMER_START, (gchar*)(gchar*)__FUNCTION__); + BookData* data = (BookData*)(engine->engine_data); + //gchar* tmp = g_utf8_strdown(word,-1); + sqlite_vm* query; + gchar* sql = NULL; + gchar* tran = NULL; + +/* + sql = g_strconcat("SELECT * FROM translations WHERE " + "word_id=(SELECT id FROM words WHERE word=\'", + tmp, + "\');", + NULL); +*/ + + /*sql = g_strconcat("SELECT * FROM translations WHERE word LIKE \'", + tmp, + "\';", + NULL);*/ + sql = sqlite_mprintf("SELECT translation FROM translations WHERE word LIKE '%q';", + word); + + gint sql_res = 0; + const gchar* end; + gchar* err = NULL; + sql_res = sqlite_compile(data->db, /* The open database */ + (const gchar*)sql, /* SQL statement to be compiled */ + &end, /* OUT: uncompiled tail of zSql */ + &query, /* OUT: the virtual machine */ + &err /* OUT: Error message. */ + ); + if(err || sql_res!=0) { + LOGS("Error while compiling query:\n%s\nreason:%s\n",sql,err); + sqlite_freemem(sql);/*g_free(sql);*/ sql = NULL; + return; + } + + gint nCol = 0; + const gchar** values = NULL; + const gchar** head = NULL; + gint status = 0; + gboolean first = TRUE; + do { + first = TRUE; + do { + if(!first) sleep(1); + first = FALSE; + status = sqlite_step(query, + &nCol, + &values, + &head + ); + if(status == SQLITE_ROW) { + if (tran != NULL){ + tran = g_strconcat(tran,"

", + (gchar*)(&(values[0][0])), NULL); + }else{ + tran = g_strdup_printf("%s

", + (gchar*)(&(values[0][0]))); + } + LOGS("Translation found :\n\"%s\"\n",tran); + } + } while((status == SQLITE_BUSY) && (status != SQLITE_ERROR)); + } while((status == SQLITE_ROW) && (status != SQLITE_ERROR)); + sqlite_finalize(query,&err); + sqlite_freemem(sql); sql = NULL; + timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + timer(TIMER_START,"callback for returning word's translation START"); + // calling callback for word translation + + data->cb_search_word_trans(tran, word, data->cb_search_word_trans_data, + ENGINE_NO_ERROR); + + timer(TIMER_STOP,"callback for returning word's translation END"); + if(data->auto_free) { + LOGS("Bookmark/%s->%s() deleting all dynamic data because " + "AUTO_FREE=TRUE\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + g_free(tran); + } + tran = NULL; +} + +//------------------------------------------------------------------------------ +void bm_engine_close(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM: engine adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine); + g_assert(engine != NULL); + + BookData* data = (BookData*)(engine->engine_data); + sqlite_close(data->db); + + LOGS("Bookmark/%s->%s() engine at adress=%p is deleted.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine); + g_free(engine); + engine = NULL; +} +//------------------------------------------------------------------------------ + +Engine* bm_engine_create(gchar* location, + EngineOptimizationFlag auto_cache, + cb_progress progress_handler, + gpointer progress_data, + gdouble seed) +{ + LOGS("Bookmark/%s->%s() called.\n" + "-->PARAM:location=\'%s\'\n" + "-->PARAM:auto_cache=%d\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + location, + (guint)auto_cache + ); + timer(TIMER_START,(gchar*)(gchar*)__FUNCTION__); + gchar* tmp = g_strdup(location); + string_to_path(&tmp); + + Engine* result = (Engine*)g_try_malloc(sizeof(Engine)); + result->engine_location = bm_engine_location; + result->engine_is_optimized = bm_engine_is_optimized; + result->engine_optimize = bm_engine_optimize; + result->engine_search_word_list = bm_engine_search_word_list; + result->engine_search_word_translation = + bm_engine_search_word_translation; + result->engine_close = bm_engine_close; + result->engine_status = bm_engine_status; + result->engine_error_message = bm_engine_status_message; + result->engine_set_callback = bm_engine_set_callback; + result->engine_set_progress_seed = bm_engine_set_progress_seed; + result->engine_set_auto_free = bm_engine_set_auto_free; + // 0.2 API: + result->engine_add_word = bm_engine_add_word; + result->engine_remove_word = bm_engine_remove_word; + result->engine_get_lang_from = bm_engine_get_lang_from; + result->engine_get_lang_to = bm_engine_get_lang_to; + result->engine_get_title = bm_engine_get_title; + result->engine_get_icon_path = bm_engine_get_icon_path; + + + BookData* data = (BookData*)g_try_malloc(sizeof(BookData)); + result->engine_data = (gpointer)data; + + LOGS("Bookmark/%s->%s() opening file...\'%s\'.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + location + ); + gchar* tmp2 = g_strconcat(tmp,"/ws_bookmarks",NULL); + gchar* err; + data->db = sqlite_open(tmp2,0600,&err); + g_free(tmp2); tmp2 = NULL; + if(!(data->db)) { + LOGS("Bookmark/%s->%s() opening bookmark file failed.%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + err + ); + g_free(err); + g_free(data); + g_free(result); + result = NULL; + } + else { + LOGS("Bookmark/%s->%s()opening dictionary file successed.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + data->dict_path = g_strdup(tmp); + data->cb_progress_caching = progress_handler; + data->cb_progress_caching_data = progress_data; + data->cb_progress_caching_seed = seed; + data->cb_progress_word_list = NULL; + data->cb_progress_word_list_data = NULL; + data->cb_progress_word_list_seed = 0.01; + data->cb_progress_word_trans = NULL; + data->cb_progress_word_trans_data = NULL; + data->cb_progress_word_trans_seed = 0.01; + + data->cb_search_word_list = NULL; + data->cb_search_word_list_data = NULL; + + data->cb_search_word_trans = NULL; + data->cb_search_word_trans_data = NULL; + + data->auto_free = FALSE; + // there is no cache mechanizm in bookmarks + } + g_free(tmp); tmp = NULL; + + timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + LOGS("Bookmark/%s->%s() returned Engine at adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ + + + +static gboolean is_Bookmark_file(gchar* file) { + LOGS("Bookmark/%s->%s() called.\n\ + -->PARAM:file=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + file + ); + gchar* err; + sqlite* tmp = sqlite_open(file,0600,&err); + if(err || tmp==NULL) { + LOGS("Wrong file! Not a sqlite database.\n"); + g_free(err); + return FALSE; + } + + gint result = 0; + gchar sql[] = "SELECT COUNT(word) FROM translations WHERE word=\'.\';"; + + result = sqlite_exec(tmp, sql, NULL, NULL, &err); + if(err || result!=0) { + LOGS("Wrong database! Not a bookmark.\n"); + g_free(err); + sqlite_close(tmp); + return FALSE; + } + sqlite_close(tmp); + return TRUE; +} +//------------------------------------------------------------------------------ + + +void bm_engine_optimize(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called for engine at adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine + ); + LOGS("Unsupported optimization mechanizm for this engine!\n"); + LOGS("Bookmark/%s->%s()'s work finished.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); +} +//------------------------------------------------------------------------------ +gboolean bm_engine_check(gchar* location) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM:location=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + location + ); + timer(TIMER_START,(gchar*)(gchar*)__FUNCTION__); + gboolean result = TRUE; + gchar* filepath = g_strdup(location); + gchar* tmp = NULL; + string_to_path(&filepath); + if (filepath == NULL) { + result = FALSE; + LOGS("Bookmark/%s->%s() location \'%s\' is not a proper " + "path!\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + location + ); + } + else { + tmp = g_strconcat(filepath,"/ws_bookmarks",NULL); + g_free(filepath); + filepath = tmp; + tmp = NULL; + + LOGS("Bookmark/%s->%s() finnal file to check is: %s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + filepath + ); + if (!g_file_test(filepath, G_FILE_TEST_IS_REGULAR)) { + LOGS("Bookmark/%s->%s() file \'%s\' does not exists!\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + filepath + ); + result = FALSE; + }; + }; + if (result != FALSE) { + result = is_Bookmark_file(filepath); + }; + + g_free(filepath); + timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + LOGS("Bookmark/%s->%s() returned bool statement=%s.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + PRINT_STATE(result) + ); + return result; +} + +//------------------------------------------------------------------------------ +gboolean bm_engine_is_optimized(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM: engine adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine + ); + g_assert(engine != NULL); + gboolean result = FALSE; + LOGS("Bookmark/%s->%s() returned bool statement=%s.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + PRINT_STATE(result) + ); + return result; +} +//------------------------------------------------------------------------------ + +void bm_engine_search_word_list(Engine* engine, gchar* pattern) +{ + LOGS("Bookmark/%s->%s() called. Searching words list\n" + "-->PARAM:engine at adress=%p\n" + "-->PARAM:pattern=\"%s\"\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine, + pattern + ); + g_assert(engine != NULL); + g_assert(pattern != NULL); + + timer(TIMER_START,(gchar*)(gchar*)__FUNCTION__); + BookData* data = (BookData*)(engine->engine_data); + if(data->cb_search_word_list == NULL) { + LOGS("Bookmark/%s->%s() callback for Word List not set. " + "Searching aborted.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + return; + }; + + + gchar* tmp = g_utf8_strdown(pattern,-1); + sqlite_vm* query = NULL; + gchar* sql = NULL; + gchar* tran = NULL; + + //LOGS("::::BOOKMARKS!!!!:::: tmp = %s, int(tmp) = %i", tmp, tmp[0]); + + + g_strstrip(tmp); + if ((int)(tmp[0]) == 42 && tmp[1] == '\0') //asterix? + { + sql = g_strconcat("SELECT DISTINCT word FROM translations;", NULL); + } + else + { + sql = g_strconcat("SELECT word FROM translations WHERE " + "word LIKE \'",tmp,"\%\';",NULL); + } + LOGS("QUERY: %s\n",sql); + gint sql_res = 0; + const gchar* end; + gchar* err = NULL; + sql_res = sqlite_compile(data->db, /* The open database */ + (const gchar*)sql, /* SQL statement to be compiled */ + &end, /* OUT: uncompiled tail of zSql */ + &query, /* OUT: the virtual machine */ + &err /* OUT: Error message. */ + ); + if(err || sql_res!=0) { + LOGS("Error while compiling query:\n%s\nreason:%s\n",sql,err); + g_free(sql); sql = NULL; + return; + }; + gint nCol = 0; + const gchar** values = NULL; + const gchar** head = NULL; + gint status = 0; + gboolean first = TRUE; + GArray* result = g_array_new(TRUE, TRUE, sizeof(gchar*) ); + do { + first = TRUE; + do { + if(!first) sleep(1); + first = FALSE;; + status = sqlite_step( + query, + &nCol, + &values, + &head + ); + if(status == SQLITE_ERROR) { + LOGS("Error while making next step\n"); + g_free(sql); sql = NULL; + return; + }; + if(status == SQLITE_ROW) { + LOGS("Fount new word: \"%s\"\n",&(values[0][0])); + gchar* tmp = g_strdup((gchar*)&(values[0][0])); + g_array_append_val(result, tmp ); + } + } while((status == SQLITE_BUSY) && (status != SQLITE_ERROR)); + } while((status == SQLITE_ROW) && (status != SQLITE_ERROR)); + sqlite_finalize(query,&err); + timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + + + timer(TIMER_START,"callback for returning words LIST START"); + // calling callback for word translation + + data->cb_search_word_list(result , pattern, data->cb_search_word_list_data, ENGINE_NO_ERROR); + + timer(TIMER_STOP,"callback for returning word LIST END"); + if(data->auto_free) { + LOGS("Bookmark/%s->%s() deleting all dynamic data because " + "AUTO_FREE=TRUE\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + g_free(tran); + } +} + +//============================================================================== +//============================================================================== +//============================================================================== +//---------------------------------------------------------- COMPLETED FUNCTIONS +//============================================================================== +// global functions +EngineModule engine_global_functions() +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + EngineModule result; + result.engine_check = bm_engine_check; + result.engine_description = bm_engine_description; + result.engine_format = bm_engine_format; + result.engine_version = bm_engine_version; + result.engine_create = bm_engine_create; + LOGS("Bookmark/%s->%s()returned EngineModule at adress=%p.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + &result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_status_message(error) +gchar* bm_engine_status_message(EngineStatus error) +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + switch (error) { + case ENGINE_NO_ERROR: + return "No error."; + case ENGINE_WRONG_FILE: + return "File which You are trying to use is wrong type."; + case ENGINE_COULDNT_READ: + return "Could not read from file."; + case ENGINE_NO_FILE: + return "There is no such a file."; + case ENGINE_OUT_OF_MEMORY: + return "There were no enough memory for this action."; + default: + return "Wrong engine's status identifier!"; + } +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_module_get_version(module) +gchar* bm_engine_version() +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_VERSION); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_module_get_format(module) +gchar* bm_engine_format() +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_FORMAT); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_module_get_description(module) +gchar* bm_engine_description() +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_DESCRIPTION); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_get_location(engine) +gchar* bm_engine_location(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM: engine adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine + ); + g_assert(engine != NULL); + BookData* data = (BookData*)(engine->engine_data); + + gchar* result; + if(data->auto_free) { + result = data->dict_path; + } + else { + result = g_strdup(data->dict_path); + } + + LOGS("Bookmark/%s->%s() returned string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_set_auto_free(engine, state) +void bm_engine_set_auto_free(Engine* engine, gboolean state) +{ + LOGS("Bookmark/%s->%s() called.\n" + "-->PARAM:engine at adress=%p\n" + "-->PARAM:state=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine, + PRINT_STATE(state) + ); + g_assert(engine != NULL); + BookData* data = (BookData*)(engine->engine_data); + + data->auto_free = state; + LOGS("Bookmark/%s->%s() Current auto_free is %s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + PRINT_STATE(data->auto_free) + ); +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_get_last_status(engine) +EngineStatus bm_engine_status(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called.\n" + "-->PARAM:engine at adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine + ); + BookData* data = (BookData*)(engine->engine_data); + LOGS("Bookmark/%s->%s() returned error code: %d\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (gint)(data->last_error) + ); + return data->last_error; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_set_progress_seed(engine, signal, val) +void bm_engine_set_progress_seed(Engine* engine, gchar* signal, gdouble seed) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + BookData* data = (BookData*)(engine->engine_data); + if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) { + data->cb_progress_caching_seed = seed; + LOGS("Bookmark/%s->%s() sets new seed=%0.2f for for signal " + "\"%s\".\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + seed, + signal + ); + } + else { + LOGS("Bookmark/%s->%s() unsupported signalfor progress: %s.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + }; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_set_callback(engine,signal,c_handler,data) +gpointer bm_engine_set_callback(Engine* engine, + gchar* signal, + gpointer c_handler, + gpointer user_data) +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + g_assert(engine != NULL); + g_assert(signal != NULL); + g_assert(c_handler != NULL); + BookData* data = (BookData*)(engine->engine_data); + if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) { + gpointer result = data->cb_progress_caching; + data->cb_progress_caching = c_handler; + data->cb_progress_caching_data = user_data; + LOGS("Bookmark/%s->%s() sets handler for signal \"%s\".\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + LOGS("Bookmark/%s->%s() Function at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)c_handler + ); + LOGS("Bookmark/%s->%s() Data at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)user_data + ); + return result; + } + else if(g_ascii_strcasecmp(signal, ENGINE_WORD_LIST_SIGNAL) == 0) { + gpointer result = data->cb_search_word_list; + data->cb_search_word_list = c_handler; + data->cb_search_word_list_data = user_data; + LOGS("Bookmark/%s->%s() sets handler for signal \"%s\".\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + LOGS("Bookmark/%s->%s() Function at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)c_handler + ); + LOGS("Bookmark/%s->%s() Data at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)user_data + ); + return result; + } + else if(g_ascii_strcasecmp(signal, + ENGINE_WORD_TRANSLATION_SIGNAL) == 0) { + gpointer result = data->cb_search_word_trans; + data->cb_search_word_trans = c_handler; + data->cb_search_word_trans_data = user_data; + LOGS("Bookmark/%s->%s() sets handler for signal \"%s\".\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + LOGS("Bookmark/%s->%s() Function at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)c_handler + ); + LOGS("Bookmark/%s->%s() Data at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)user_data + ); + return result; + } + else { + g_warning("Bookmark/%s->%s() unsupported signal: %s.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + return NULL; + } +} + + + + + + +//============================================================================== +//============================================================================== +//============================================================================== +//---------------------------------------------------------- HELPFULLY FUNCTIONS +//============================================================================== + +//------------------------------------------------------------------------------ +static gchar* string_to_path(gchar** string) { + LOGS("Bookmark/%s->%s() called.\n\ + -->PARAM:string=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + string[0] + ); + gchar* arg = string[0]; + gchar* new = NULL; + // cleaning from leading and trailing whitespaces + g_strstrip(arg); + // add current directory if this is not absolute directory + if (!g_path_is_absolute(arg)) { + gchar* tmp = g_get_current_dir(); + new = g_strconcat(tmp,"/",arg,NULL); + g_free(arg); arg = new; new = NULL; + }; + // this is not a directory + if (!g_file_test(arg, G_FILE_TEST_IS_DIR)) { + // if this is wrong filepath, string was wrong + if (!g_file_test(arg, G_FILE_TEST_IS_REGULAR)) { + g_free(arg); + new = NULL; + } + //if this is a file, remove filename + else + { + new = g_path_get_dirname (arg); + g_free(arg); + } + } + // this is a directory + else { + // remove suffix "/" if neded... + if (g_str_has_suffix(arg,"/") ) { + new = g_path_get_dirname (arg); + g_free(arg); + } + else { + new = arg; + } + }; + // now in new should be proper filepath, if not, string was wrong + if (!g_file_test(new, G_FILE_TEST_IS_DIR)) { + // if that directory does not exist, passed string wasn't proper + g_free(new); + new = NULL; + }; + // replace string under passed address + string[0] = new; + LOGS("Bookmark/%s->%s() returned string=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + string[0] + ); + return new; +} +//------------------------------------------------------------------------------ +static double timer(gboolean start, gchar* message) +{ + static GArray* stack = NULL; + static gboolean first_run = TRUE; + static struct timeval actual_time; + static struct timeval last_time; + static struct timeval result; + static double seconds = 0.0; + if(first_run) { + first_run = FALSE; + stack = g_array_new(TRUE, TRUE, sizeof(struct timeval)); + }; + + if (start) { + LOGS("Bookmark->%s() start timer for function '%s()'.\n", + (gchar*)__FUNCTION__, + message + ); + g_array_prepend_val(stack, actual_time); + gettimeofday(&g_array_index(stack, struct timeval, 0),NULL); + return -1.0; + } + // we just want to end some timer - print some information about + // working time; + else { + gettimeofday(&actual_time,NULL); + last_time = g_array_index(stack, struct timeval, 0); + g_array_remove_index(stack, 0); + + if (actual_time.tv_usec < last_time.tv_usec) { + int nsec = (last_time.tv_usec - actual_time.tv_usec) / + (1000000 + 1); + last_time.tv_usec -= 1000000 * nsec; + last_time.tv_sec += nsec; + } + if (actual_time.tv_usec - last_time.tv_usec > 1000000) { + int nsec = (last_time.tv_usec - actual_time.tv_usec) / + 1000000; + last_time.tv_usec += 1000000 * nsec; + last_time.tv_sec -= nsec; + } + result.tv_sec = actual_time.tv_sec - last_time.tv_sec; + result.tv_usec = actual_time.tv_usec - last_time.tv_usec; + seconds = (((double)(result.tv_usec)) / 1e6) + + ((double)(result.tv_sec)); + + LOGS("Bookmark->%s() function \'%s()\' was working for: %g " + "[s] or %ld [us].\n", + (gchar*)__FUNCTION__, + message, + seconds, + ((long)(result.tv_sec*1e6)+(result.tv_usec)) + ); + // stack is empty so we delete everything + if(stack->len == 0) + { + g_array_free(stack, TRUE); + first_run = TRUE; + } + } + return seconds; +} +//------------------------------------------------------------------------------ + + + diff --git a/src/bookmarks/sql/src/test.c b/src/bookmarks/sql/src/test.c new file mode 100644 index 0000000..b89a9a7 --- /dev/null +++ b/src/bookmarks/sql/src/test.c @@ -0,0 +1,144 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#include +#include +#include +#include + + +getting_additional get_functions; // additinal functions for concrete module (e.g. XDXF) + +void print_list(GArray* list, gchar* pattern, gpointer user_data, EngineStatus error) { + printf((gchar*)user_data,pattern); + int i = 0; + while(g_array_index(list, gchar*, i) != NULL) + { + printf(" %d. : %s\n",i+1,g_array_index(list, gchar*, i)); + i++; + } + printf("--------------------------------------------------\n"); +} + +void print_translation(gchar* translation, gchar* word, gpointer user_data, EngineStatus error) { + printf((gchar*)user_data,word); + printf("%s\n\nTRANSLATION ENDS.\n",translation); +} + +void caching_progress(gdouble value, gpointer user_data, EngineStatus error) { + printf((gchar*)user_data,value); +} + +int main(int argc, char** argv) +{ + char* nameApp = "StarDictEngine test: "; + printf("%sStarting test program of module: dictionary_engine.\n",nameApp); + + + gchar* current_directory = g_get_current_dir(); + printf("%sCurrent directory: %s\n",nameApp,current_directory); + gchar* library_to_path = g_strconcat(current_directory, "/ws_bookmark.so", NULL); + printf("%sEngine library should be in location:\n\t%s\n",nameApp,library_to_path); + + GModule *library = g_module_open(library_to_path, G_MODULE_BIND_LAZY); + if(!library) { + printf("%sLoading module failed. \nReason: %s\n",nameApp,g_module_error()); + return 1; + }; + + //dict_eng_module_get_global_functions(library,get_functions); + g_module_symbol ( (library),_GLOBAL_FUNCTIONS_NAME_, (gpointer)&get_functions); + if(get_functions == NULL) { + printf("%sLoading function failed\n",nameApp); + return 2; + } + else printf("%sLoading function OK\n",nameApp); + + EngineModule module = get_functions(); + printf("Module description: %s\n",dict_eng_module_get_description(module)); + Engine* sd; + + gboolean is_compatible = dict_eng_module_check(module,"/home/str/whitestork/engines/bookmark/ws_bookmarks"); + if(is_compatible == TRUE) + { + printf("Location is compatible with enigne!\n"); + } + else { + printf("Location is not compatible with enigne!\n"); + return 1; + } + + //printf("%sCheck OK. Module description: %s\n", nameApp, dict_eng_module_get_description(module)); + + //xdxf = dict_eng_module_create_ext(module, "/home/lukasz/MyDocs/repo/WhiteStork/trunk/engine/bin" , ENGINE_CREATE, caching_progress, "Current progress of caching is: %0.2f.\n", 0.03 ); + //home/stranger/whitestork/engine0.2/ +// xdxf = dict_eng_module_create(module, "/home/stranger/whitestork/engine0.2/" , ENGINE_NO); +// dict_eng_set_callback(xdxf, ENGINE_PROGRESS_CACHING, caching_progress, "Current progress of caching is: %0.2f.\n"); +// dict_eng_set_progress_seed(xdxf, ENGINE_PROGRESS_CACHING, 0.02); + +/* if(dict_eng_is_optimized(xdxf) == FALSE) + { + printf("Dictionary has no cache!\nCreating cache file....\n"); + dict_eng_optimize(xdxf); + } + else { + printf("Dictionary has already cache file!\n"); + }*/ + sd = dict_eng_module_create(module, + "/home/str/whitestork/engines/bookmark/ws_bookmarks" , + ENGINE_CREATE); + printf("Lokacja: %s\n",dict_eng_get_location(sd)); + + dict_eng_set_callback(sd, + ENGINE_WORD_LIST_SIGNAL, + print_list, + "Word list matches to pattern: %s\n" + ); + dict_eng_set_callback(sd, + ENGINE_WORD_TRANSLATION_SIGNAL , + print_translation, + "Translation for word\'%s\':\n"); + + dict_eng_search_word_list(sd,"12"); + //dict_eng_search_word_translation(sd,"1 word"); + + dict_eng_remove_word(sd, "stranger"); + dict_eng_remove_word(sd, "gandzia"); + dict_eng_remove_word(sd, "lukas"); + dict_eng_add_word(sd, "stranger", "autor pluginu tego wlasnie to jest!"); + dict_eng_add_word(sd, "gandzia", "rulez"); + dict_eng_add_word(sd, "lukas", "pawlik"); + dict_eng_remove_word(sd, "stranger"); + + dict_eng_search_word_translation(sd,"stranger"); + + dict_eng_add_word(sd, "stranger", "autor pluginu tego wlasnie to jest!"); + dict_eng_search_word_translation(sd,"stranger"); + dict_eng_search_word_list(sd,"gandzia"); + + printf("Lang FROM:%s\n",dict_eng_get_lang_from(sd)); + printf(" Lang TO:%s\n",dict_eng_get_lang_to(sd)); + printf(" Title:%s\n",dict_eng_get_title(sd)); + printf("Icon path:%s\n",dict_eng_get_icon_path(sd)); + + dict_eng_destroy(sd); + printf("%sClosed.\n",nameApp); + return 0; +} + diff --git a/src/bookmarks/sql/src/testMakeDatabase.c b/src/bookmarks/sql/src/testMakeDatabase.c new file mode 100644 index 0000000..7ca65e1 --- /dev/null +++ b/src/bookmarks/sql/src/testMakeDatabase.c @@ -0,0 +1,135 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ + +#include +#include +#include + +const guint records_number = 1000; + +// ---------------------------------------------------------------------------------- +sqlite* database_make(gchar* path) { + gchar* buffer = NULL; + sqlite* result = NULL; + // creatingh database + result = sqlite_open(path, + 0600, + &buffer); + // check if everything was okey + if(!result) { + g_printf("Error while trying to create database:\n%s\n",buffer); + g_free(buffer); buffer = NULL; + return NULL; + }; + // return pointer to database + return result; +} +// ---------------------------------------------------------------------------------- +gint database_add_test_table(sqlite* db) { + gint result = 0; + //gchar sql[] = "CREATE TABLE words(id INTEGER PRIMARY KEY, word TEXT UNIQUE);"; + gchar sql2[] = "CREATE TABLE translations(id INTEGER PRIMARY KEY, word TEXT, translation TEXT);"; + gchar* err = NULL; +/* + result = sqlite_exec(db, sql, NULL, NULL, &err); + if(err || result!=0) { + g_printf("Error while creating \'words\' table:\n%s\n",err); + return 1; + } +*/ + result = sqlite_exec(db, sql2, NULL, NULL, &err); + if(err || result!=0) { + g_printf("Error while creating \'translations\' table:\n%s\n",err); + return 2; + } + + return result; +} +// ---------------------------------------------------------------------------------- +gint database_add_test_record(sqlite* db, guint i) { + gint result = 0; + gchar* sql = NULL; + gchar* err = NULL; + gint last_id = 0; + gint word_count = 1; + gchar buffer[] = " "; + gchar last_char[] = " "; + gchar tran[] = "this is a translation number 10.000 for word 10.000 word <-----"; + g_sprintf(buffer,"%d word",i); +/* + sql = g_strconcat("INSERT INTO words VALUES(NULL,\'",buffer,"\');", NULL); + result = sqlite_exec(db, sql, NULL, NULL, &err); + if(err || result!=0) { + g_printf("Error while trying to add new word %d:\n%s\n",i,err); + g_free(sql); + return 1; + } + g_free(sql); + last_id = sqlite_last_insert_rowid(db); + g_sprintf(last_char,"%d",last_id); +*/ + if(i == 5000) { + word_count = 5; + g_printf("Adding more records for word - test\n"); + } + gint j; + for(j=0; j + Copyright (C) + + 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. + +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. + + , 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 Lesser General +Public License instead of this License. \ No newline at end of file diff --git a/src/bookmarks/sql3/Makefile b/src/bookmarks/sql3/Makefile new file mode 100644 index 0000000..744e9f2 --- /dev/null +++ b/src/bookmarks/sql3/Makefile @@ -0,0 +1,48 @@ +COMPILER = gcc +DEBUG = -Wall -g +SOURCES = ./src +INCLUDE = include +INCLUDE_ENGINE = ../../../include +LIBS = `pkg-config --libs glib-2.0 gmodule-2.0` -lsqlite3 +FLAGS = `pkg-config --cflags glib-2.0 gmodule-2.0` -I${INCLUDE} -I${INCLUDE_ENGINE} ${DEBUG} +BINARIES = bin +FINAL = ../../../bin/ws_bookmark.so + + +${FINAL}: ${BINARIES}/bookmark.o ${SOURCES}/engine_bookmark.c + @gcc -shared -fPIC ${FLAGS} ${LIBS} ${BINARIES}/bookmark.o -o ${FINAL} + +${BINARIES}/bookmark.o: ${SOURCES}/engine_bookmark.c + @gcc -c -fPIC -o ${BINARIES}/bookmark.o ${SOURCES}/engine_bookmark.c ${FLAGS} + +clean: + @-rm -f ${BINARIES}/* + @-rm -f ${FINAL} + @echo -e -n "Project's 'BookmarkEngine' directories has been cleaned.\n" + +cleandata: + @-rm -f ws_bookmarks-journal + @-rm -f ws_bookmarks + + +data: ${SOURCES}/testMakeDatabase.c + @echo -e -n "Compiling testDatabase...\n" + @gcc -o ${SOURCES}/testDatabase ${SOURCES}/testMakeDatabase.c ${FLAGS} ${LIBS} + +datarun: data + @run-standalone.sh src/testDatabase + +test: test.o + @echo "Linking test program..." + @gcc ${LIBS} ${DEBUG} -o ${SOURCES}/test ${BINARIES}/test.o + @echo -e "Building test program finished.\n" + +test.o: + @echo "Compiling test program..." + @gcc ${FLAGS} ${DEBUG} -c -o ${BINARIES}/test.o ${SOURCES}/test.c + +check: + @echo "Running test program:" + @run-standalone.sh ${SOURCES}/test + + \ No newline at end of file diff --git a/src/bookmarks/sql3/include/engine_bookmark.h b/src/bookmarks/sql3/include/engine_bookmark.h new file mode 100644 index 0000000..ecea43f --- /dev/null +++ b/src/bookmarks/sql3/include/engine_bookmark.h @@ -0,0 +1,210 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#ifndef _DICTIONARY_ENGINE_BOOKMARK +#define _DICTIONARY_ENGINE_BOOKMARK + +#ifdef __cplusplus + extern "C" { +#endif + +//______________________________________________________________________________ +// ***************************************************************************** +//************************************************************* HEADERS SECTION: +//------------------------------------------------------------------------------ +// headers with unix types/functions - only for timers +#include +#include +#include +#include +#include +//------------------------------------------------------------------------------ +// header with GLIB definitions/functions/types +#include +//------------------------------------------------------------------------------ +// header wit engine API +#include "dictionary_engine.h" +//------------------------------------------------------------------------------ +// header wit sqlite 2.x API +#include +//------------------------------------------------------------------------------ + +//______________________________________________________________________________ +// ***************************************************************************** +//********************************************************* DEFINITIONS SECTION: +//------------------------------------------------------------------------------ +// definitions for timer function - flag telling if we want to start or stop +// timing +#define TIMER_START TRUE +#define TIMER_STOP FALSE +//------------------------------------------------------------------------------ +// definitions of version and format which engine handles +static const gchar* DIC_ENG_VERSION = "0.1"; +static const gchar* DIC_ENG_FORMAT = "Users' Bookmarks"; +static const gchar* DIC_ENG_DESCRIPTION = "This module handles users' bookmarks."; + +//------------------------------------------------------------------------------ +// macro for "printing" gboolean statement - "TRUE" or "FALSE" +#define PRINT_STATE(state) ( (state) ? "TRUE" : "FALSE" ) +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//****************************************** DATA STRUCTURE DEFINITIONS SECTION: +//------------------------------------------------------------------------------ +/** \brief Internal data structure of XDXF Engine. + */ +struct _BookData { + sqlite3* db; + + gchar* dict_path; + EngineStatus last_error; + gboolean auto_free; + + cb_progress cb_progress_caching; + gpointer cb_progress_caching_data; + gdouble cb_progress_caching_seed; + + cb_progress cb_progress_word_list; + gpointer cb_progress_word_list_data; + gdouble cb_progress_word_list_seed; + + cb_progress cb_progress_word_trans; + gpointer cb_progress_word_trans_data; + gdouble cb_progress_word_trans_seed; + + cb_word_list cb_search_word_list; + gpointer cb_search_word_list_data; + + cb_word_translation cb_search_word_trans; + gpointer cb_search_word_trans_data; +}; +typedef struct _BookData BookData; +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//************************************************ ADDITIONAL FUNCTIONS SECTION: +//------------------------------------------------------------------------------ +// returning concrete part of file +//static gchar* read_file_part(FilePart* part, GnomeVFSHandle* file); +//------------------------------------------------------------------------------ +// convert string to proper path name (no filename, no "/" at the ned, file +// exist) +static gchar* string_to_path(gchar** string); +//------------------------------------------------------------------------------ +// tells if file is in XDXF format (file should exist) +//static gboolean is_xdxf_file(gchar* file); +//------------------------------------------------------------------------------ +// start/stop timers - returnet -1.0 if we start or seconds passed from start +// if we want to stop timer +static double timer(gboolean start, gchar* message); +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//****************************************************** MAIN FUNCTIONS SECTION: +//------------------------------------------------------------------------------ +gboolean bm_engine_add_word(Engine* engine, + gchar* word, + gchar* translation); +//------------------------------------------------------------------------------ +gboolean bm_engine_remove_word(Engine* engine, + gchar* word); +//------------------------------------------------------------------------------ +gchar* bm_engine_get_lang_from(Engine* engine); +//------------------------------------------------------------------------------ +gchar* bm_engine_get_lang_to(Engine* engine); +//------------------------------------------------------------------------------ +gchar* bm_engine_get_title(Engine* engine); +//------------------------------------------------------------------------------ +gchar* bm_engine_get_icon_path(Engine* engine); + + + +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_check(module,location) function +gboolean bm_engine_check(gchar* location); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_get_description(module) function +gchar* bm_engine_description(); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_get_format(module) function +gchar* bm_engine_format(); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_get_version(module) function +gchar* bm_engine_version(); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_create(module,location,flags) and +// dict_eng_module_create_ext(module,location,flags) functions +Engine* bm_engine_create(gchar* location, + EngineOptimizationFlag flags, + cb_progress progress_handler, + gpointer progress_data, + gdouble seed); +//------------------------------------------------------------------------------ +// implementation of dict_eng_destroy(engine) function +void bm_engine_close(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_get_location(engine) function +gchar* bm_engine_location(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_optimize(engine) function +void bm_engine_optimize(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_is_optimized( engine ) function +gboolean bm_engine_is_optimized(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_set_auto_free(engine, state) function +void bm_engine_set_auto_free(Engine* engine, gboolean state); +//------------------------------------------------------------------------------ +// implementation of dict_eng_set_callback(engine,signal,c_handler,data) +// function +gpointer bm_engine_set_callback(Engine* engine, + gchar* event, + gpointer c_handler, + gpointer user_data); +//------------------------------------------------------------------------------ +// implementation of dict_eng_set_progress_seed(engine, signal, val) function +void bm_engine_set_progress_seed(Engine* engine, + gchar* signal, + gdouble seed); +//------------------------------------------------------------------------------ +// implementation ofdict_eng_search_word_list(engine,pattern) function +void bm_engine_search_word_list(Engine* engine, gchar* pattern); +//------------------------------------------------------------------------------ +// implementation of dict_eng_search_word_translation(engine,word) function +void bm_engine_search_word_translation(Engine* engine, gchar* word); +//------------------------------------------------------------------------------ +// implementation of dict_eng_get_last_state(engine) function +EngineStatus bm_engine_status(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_state_message(error) function +gchar* bm_engine_status_message(EngineStatus error); +//------------------------------------------------------------------------------ +// implementation of engine_global_functions(void) function +EngineModule engine_global_functions(); + +#ifdef __cplusplus +} +#endif +#endif /* #ifndef _DICTIONARY_ENGINE_STARDICT */ diff --git a/src/bookmarks/sql3/src/engine_bookmark.c b/src/bookmarks/sql3/src/engine_bookmark.c new file mode 100644 index 0000000..c722cb7 --- /dev/null +++ b/src/bookmarks/sql3/src/engine_bookmark.c @@ -0,0 +1,1020 @@ +/****************************************************************************** +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +******************************************************************************/ + +// header with data structure and function definition for XDXF engine. +// Also Engine API. +#include +//------------------------------------------------------------------------------ + +#ifndef NOLOGS +#include +#include +#include +#endif + +#define LOGS g_debug + +/*inline void LOGS(gchar* frm, ...) { +#ifndef NOLOGS + //g_printf(frm); +#endif +}*/ + +//============================================================================== +//============================================================================== +//============================================================================== +//-------------------------------------- FUNCTION FROM API 0.2 !!! +//============================================================================== +int get_id(void* data,int n,char** argv,char** names) { + int len = strlen(&(argv[0][0])); + memcpy(data,&(argv[0][0]), len); + gchar* tmp = (gchar*)data; + tmp[len] = 0; + return 0; +} + +gboolean bm_engine_add_word(Engine* engine, + gchar* word, + gchar* translation) { + gint sql_res = 0; + gchar* err = NULL; + gboolean result = TRUE; + gchar* sql = NULL; + + LOGS("Bookmark/%s->%s() called. Param\nEngine at address: %p\n" + "word: %s\ntranslation address: %p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine, + word, + translation + ); + g_assert(engine != NULL); + g_assert(word != NULL); + g_assert(translation != NULL); + + // start timer for this function + timer(TIMER_START, (gchar*)(gchar*)__FUNCTION__); + + BookData* data = (BookData*)(engine->engine_data); + sql = sqlite3_mprintf( + "INSERT INTO translations VALUES(NULL, '%q', '%q');", + word, translation); + sql_res = sqlite3_exec(data->db, sql, NULL, NULL, &err); + if(err || sql_res!=0) { + LOGS("Error while adding translation for word %s \nreason:%s\n\n", word, err); + result = FALSE; + } + sqlite3_free(sql); sql = NULL; + + timer(TIMER_STOP, (gchar*)(gchar*)__FUNCTION__); + return result; +} +//------------------------------------------------------------------------------ +gboolean bm_engine_remove_word(Engine* engine, gchar* word) { + gint sql_res = 0; + gchar* err = NULL; + gboolean result = TRUE; + + LOGS("Bookmark/%s->%s() called. Param\nEngine at address: %p\n" + "word: %s\n",(gchar*)__FILE__,(gchar*)__FUNCTION__,engine,word); + g_assert(engine != NULL); + g_assert(word != NULL); + timer(TIMER_START, (gchar*)(gchar*)__FUNCTION__); + + BookData* data = (BookData*)(engine->engine_data); + gchar* sql = sqlite3_mprintf( + "DELETE FROM translations WHERE word LIKE '%q';", + word); + sql_res = sqlite3_exec(data->db, sql, NULL, NULL, &err); + if(err || sql_res!=0) { + LOGS("Error while deleting \'%s\' <-> reason:\n%s\n",word,err); + sqlite3_free(sql); sql = NULL; + return FALSE; + } + sqlite3_free(sql); sql = NULL; + + timer(TIMER_STOP, (gchar*)(gchar*)__FUNCTION__); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_get_lang_from(Engine* engine) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup("any"); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_get_lang_to(Engine* engine) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup("any"); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_get_title(Engine* engine) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strconcat(g_get_user_name(),"s' bookmarks",NULL); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_get_icon_path(Engine* engine) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup("/usr/share/pixmaps/ws_eng_bookmark_icon.png"); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} + +//============================================================================== +//============================================================================== +//============================================================================== +//-------------------------------------- FUNCTION TO WRITE (NOT IMPLEMENTED YET) +//============================================================================== + +//------------------------------------------------------------------------------ +// searching word by concrete engine +void bm_engine_search_word_translation(Engine* engine, gchar* word) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM:engine at adress=%p\n" + "-->PARAM:word=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine, + word + ); + g_assert(engine != NULL); + g_assert(word != NULL); + // start timer for this function + timer(TIMER_START, (gchar*)(gchar*)__FUNCTION__); + BookData* data = (BookData*)(engine->engine_data); + gchar* tmp = g_utf8_strdown(word,-1); + //sqlite3_vm* query; + gchar* sql = NULL; + gchar* tran = NULL; + sqlite3_stmt *query;//ppStmt + const char *pzTail; +/* + sql = g_strconcat("SELECT * FROM translations WHERE " + "word_id=(SELECT id FROM words WHERE word=\'", + tmp, + "\');", + NULL); +*/ + + /*sql = g_strconcat("SELECT * FROM translations WHERE word LIKE \'", + tmp, + "\';", + NULL);*/ + + sql = sqlite3_mprintf( + "SELECT * FROM translations WHERE word LIKE '%q';", + tmp); + + g_debug("Query text: %s", sql); + gint sql_res = 0; + // const gchar* end; + //gchar* err = NULL; + sql_res = sqlite3_prepare( + data->db,/* Database handle */ + (const gchar *)sql,/* SQL statement, UTF-8 encoded */ + -1,/* Length of zSql in bytes. */ + &query,/* OUT: Statement handle */ + &pzTail/* OUT: Pointer to unused portion of zSql */ + ); + if (sql_res != SQLITE_OK) + { + LOGS("Error while compiling query:\n%s\nreason: %d\n",sql, sql_res); + sqlite3_free(sql); sql = NULL; + data->cb_search_word_trans(NULL, NULL, + data->cb_search_word_trans_data, + ENGINE_NO_ERROR); + return; + } + gint status = 0; + gboolean first = TRUE; + do { + first = TRUE; + do { + if(!first) sleep(1); + first = FALSE; + status = sqlite3_step(query); + if(status == SQLITE_ROW) { + if (tran != NULL){ + tran = g_strconcat(tran,"

", + sqlite3_column_text(query, 2), + NULL); + }else{ + tran = g_strdup_printf("%s

", + sqlite3_column_text(query, 2)); + } + LOGS("Translation found :\n\"%s\"\n",tran); + + } + } while((status == SQLITE_BUSY) && (status != SQLITE_ERROR)); + } while((status == SQLITE_ROW) && (status != SQLITE_ERROR)); + sqlite3_finalize(query); + + + timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + timer(TIMER_START,"callback for returning word's translation START"); + // calling callback for word translation + + data->cb_search_word_trans(tran, word, data->cb_search_word_trans_data, + ENGINE_NO_ERROR); + sqlite3_free(sql); sql = NULL; + timer(TIMER_STOP,"callback for returning word's translation END"); + if(data->auto_free) { + LOGS("Bookmark/%s->%s() deleting all dynamic data because " + "AUTO_FREE=TRUE\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + g_free(tran); + } + tran = NULL; +} + +//------------------------------------------------------------------------------ +void bm_engine_close(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM: engine adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine); + g_assert(engine != NULL); + + BookData* data = (BookData*)(engine->engine_data); + sqlite3_close(data->db); + + LOGS("Bookmark/%s->%s() engine at adress=%p is deleted.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine); + g_free(engine); + engine = NULL; +} +//------------------------------------------------------------------------------ + +Engine* bm_engine_create(gchar* location, + EngineOptimizationFlag auto_cache, + cb_progress progress_handler, + gpointer progress_data, + gdouble seed) +{ + LOGS("Bookmark/%s->%s() called.\n" + "-->PARAM:location=\'%s\'\n" + "-->PARAM:auto_cache=%d\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + location, + (guint)auto_cache + ); + timer(TIMER_START,(gchar*)(gchar*)__FUNCTION__); + + gchar* tmp = g_strdup(location); + string_to_path(&tmp); + + Engine* result = (Engine*)g_try_malloc(sizeof(Engine)); + result->engine_location = bm_engine_location; + result->engine_is_optimized = bm_engine_is_optimized; + result->engine_optimize = bm_engine_optimize; + result->engine_search_word_list = bm_engine_search_word_list; + result->engine_search_word_translation = + bm_engine_search_word_translation; + result->engine_close = bm_engine_close; + result->engine_status = bm_engine_status; + result->engine_error_message = bm_engine_status_message; + result->engine_set_callback = bm_engine_set_callback; + result->engine_set_progress_seed = bm_engine_set_progress_seed; + result->engine_set_auto_free = bm_engine_set_auto_free; + // 0.2 API: + result->engine_add_word = bm_engine_add_word; + result->engine_remove_word = bm_engine_remove_word; + result->engine_get_lang_from = bm_engine_get_lang_from; + result->engine_get_lang_to = bm_engine_get_lang_to; + result->engine_get_title = bm_engine_get_title; + result->engine_get_icon_path = bm_engine_get_icon_path; + + + BookData* data = (BookData*)g_try_malloc(sizeof(BookData)); + result->engine_data = (gpointer)data; + + LOGS("Bookmark/%s->%s() opening file...\'%s\'.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + location + ); + gchar* tmp2 = g_strconcat(tmp,"/ws_bookmarks3",NULL); + //gchar* err; + gint res = sqlite3_open(tmp2,&data->db); + g_free(tmp2); tmp2 = NULL; + if(res != SQLITE_OK) { + LOGS("Bookmark/%s->%s() opening bookmark file failed.%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + sqlite3_errmsg(data->db) + ); + //g_free(err); + g_free(data); + g_free(result); + result = NULL; + } + else { + LOGS("Bookmark/%s->%s()opening dictionary file successed.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + data->dict_path = g_strdup(tmp); + data->cb_progress_caching = progress_handler; + data->cb_progress_caching_data = progress_data; + data->cb_progress_caching_seed = seed; + data->cb_progress_word_list = NULL; + data->cb_progress_word_list_data = NULL; + data->cb_progress_word_list_seed = 0.01; + data->cb_progress_word_trans = NULL; + data->cb_progress_word_trans_data = NULL; + data->cb_progress_word_trans_seed = 0.01; + + data->cb_search_word_list = NULL; + data->cb_search_word_list_data = NULL; + + data->cb_search_word_trans = NULL; + data->cb_search_word_trans_data = NULL; + + data->auto_free = FALSE; + // there is no cache mechanizm in bookmarks + } + g_free(tmp); tmp = NULL; + + timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + LOGS("Bookmark/%s->%s() returned Engine at adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ + + + +static gboolean is_Bookmark_file(gchar* file) { + LOGS("Bookmark/%s->%s() called.\n\ + -->PARAM:file=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + file + ); + gchar* err = NULL; + sqlite3* tmp = NULL; + gint result = sqlite3_open(file, &tmp); + if(result != SQLITE_OK) { + LOGS("Wrong file! Not a sqlite database.\n"); + //g_free(err); + sqlite3_close(tmp); + return FALSE; + } + + + gchar sql[] = "SELECT COUNT(word) FROM translations WHERE word=\'.\';"; + result = sqlite3_exec(tmp, sql, NULL, NULL, &err); + if(err || result!=0) { + LOGS("Wrong database! Not a bookmark.\n"); + g_free(err); + sqlite3_close(tmp); + return FALSE; + } + sqlite3_close(tmp); + return TRUE; +} +//------------------------------------------------------------------------------ + + +void bm_engine_optimize(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called for engine at adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine + ); + LOGS("Unsupported optimization mechanizm for this engine!\n"); + LOGS("Bookmark/%s->%s()'s work finished.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); +} +//------------------------------------------------------------------------------ +gboolean bm_engine_check(gchar* location) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM:location=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + location + ); + timer(TIMER_START,(gchar*)(gchar*)__FUNCTION__); + gboolean result = TRUE; + gchar* filepath = g_strdup(location); + gchar* tmp = NULL; + + string_to_path(&filepath); + if (filepath == NULL) { + result = FALSE; + LOGS("Bookmark/%s->%s() location \'%s\' is not a proper " + "path!\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + location + ); + } + else { + tmp = g_strconcat(filepath,"/ws_bookmarks3",NULL); + g_free(filepath); + filepath = tmp; + tmp = NULL; + + LOGS("Bookmark/%s->%s() finnal file to check is: %s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + filepath + ); + if (!g_file_test(filepath, G_FILE_TEST_IS_REGULAR)) { + LOGS("Bookmark/%s->%s() file \'%s\' does not exists!\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + filepath + ); + result = FALSE; + }; + }; + if (result != FALSE) { + result = is_Bookmark_file(filepath); + }; + + g_free(filepath); + timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + LOGS("Bookmark/%s->%s() returned bool statement=%s.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + PRINT_STATE(result) + ); + return result; +} + +//------------------------------------------------------------------------------ +gboolean bm_engine_is_optimized(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM: engine adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine + ); + g_assert(engine != NULL); + gboolean result = FALSE; + LOGS("Bookmark/%s->%s() returned bool statement=%s.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + PRINT_STATE(result) + ); + return result; +} +//------------------------------------------------------------------------------ + +void bm_engine_search_word_list(Engine* engine, gchar* pattern) +{ + LOGS("Bookmark/%s->%s() called. Searching words list\n" + "-->PARAM:engine at adress=%p\n" + "-->PARAM:pattern=\"%s\"\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine, + pattern + ); + g_assert(engine != NULL); + g_assert(pattern != NULL); + + timer(TIMER_START,(gchar*)(gchar*)__FUNCTION__); + BookData* data = (BookData*)(engine->engine_data); + if(data->cb_search_word_list == NULL) { + LOGS("Bookmark/%s->%s() callback for Word List not set. " + "Searching aborted.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + return; + }; + + + gchar* tmp = g_utf8_strdown(pattern,-1); + sqlite3_stmt *query;//ppStmt + const char *pzTail; + gchar* sql = NULL; + gchar* tran = NULL; + g_strstrip(tmp); + if ((int)(tmp[0]) == 42 && tmp[1] == '\0') //asterix? + { + sql = sqlite3_mprintf("SELECT DISTINCT word FROM translations;"); + } + else + { + sql = sqlite3_mprintf( + "SELECT DISTINCT word FROM translations WHERE word LIKE'%q%%';", tmp); + } + /*sql = g_strconcat("SELECT word FROM translations WHERE " + "word LIKE \'",tmp,"\%\';",NULL);*/ + LOGS("QUERY: %s\n",sql); + gint sql_res = 0; + sql_res = sqlite3_prepare( + data->db,/* Database handle */ + (const gchar *)sql,/* SQL statement, UTF-8 encoded */ + -1,/* Length of zSql in bytes. */ + &query,/* OUT: Statement handle */ + &pzTail/* OUT: Pointer to unused portion of zSql */ + ); + if (sql_res != SQLITE_OK) + { + LOGS("Error while compiling query:\n%s\nreason:%d\n",sql, + sql_res); + sqlite3_free(sql); sql = NULL; + return; + } + gint status = 0; + gboolean first = TRUE; + GArray* result = g_array_new(TRUE, TRUE, sizeof(gchar*) ); + do { + first = TRUE; + do { + if(!first) sleep(1); + first = FALSE;; + /*status = sqlite3_step( + query, + &nCol, + &values, + &head + );*/ + status = sqlite3_step(query); + if(status == SQLITE_ERROR) { + LOGS("Error while making next step\n"); + sqlite3_free(sql); sql = NULL; + data->cb_search_word_list(NULL , NULL, + data->cb_search_word_list_data, ENGINE_NO_ERROR); + return; + }; + /*if(status == SQLITE_ROW) { + LOGS("Fount new word: \"%s\"\n",&(values[0][0])); + gchar* tmp = g_strdup((gchar*)&(values[0][0])); + g_array_append_val(result, tmp ); + }*/ + if(status == SQLITE_ROW) { + gchar* tmp = g_strdup( + sqlite3_column_text(query, 0)); + LOGS("Found new word: \"%s\"\n", tmp); + g_array_append_val(result, tmp); + } + } while((status == SQLITE_BUSY) && (status != SQLITE_ERROR)); + } while((status == SQLITE_ROW) && (status != SQLITE_ERROR)); + sqlite3_finalize(query); + timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + + + timer(TIMER_START,"callback for returning words LIST START"); + // calling callback for word translation + + data->cb_search_word_list(result , pattern, + data->cb_search_word_list_data, ENGINE_NO_ERROR); + + timer(TIMER_STOP,"callback for returning word LIST END"); + if(data->auto_free) { + LOGS("Bookmark/%s->%s() deleting all dynamic data because " + "AUTO_FREE=TRUE\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + g_free(tran); + } +} + +//============================================================================== +//============================================================================== +//============================================================================== +//---------------------------------------------------------- COMPLETED FUNCTIONS +//============================================================================== +// global functions +EngineModule engine_global_functions() +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + EngineModule result; + result.engine_check = bm_engine_check; + result.engine_description = bm_engine_description; + result.engine_format = bm_engine_format; + result.engine_version = bm_engine_version; + result.engine_create = bm_engine_create; + LOGS("Bookmark/%s->%s()returned EngineModule at adress=%p.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_status_message(error) +gchar* bm_engine_status_message(EngineStatus error) +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + switch (error) { + case ENGINE_NO_ERROR: + return "No error."; + case ENGINE_WRONG_FILE: + return "File which You are trying to use is wrong type."; + case ENGINE_COULDNT_READ: + return "Could not read from file."; + case ENGINE_NO_FILE: + return "There is no such a file."; + case ENGINE_OUT_OF_MEMORY: + return "There were no enough memory for this action."; + default: + return "Wrong engine's status identifier!"; + } +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_module_get_version(module) +gchar* bm_engine_version() +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_VERSION); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_module_get_format(module) +gchar* bm_engine_format() +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_FORMAT); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_module_get_description(module) +gchar* bm_engine_description() +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_DESCRIPTION); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_get_location(engine) +gchar* bm_engine_location(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM: engine adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine + ); + g_assert(engine != NULL); + BookData* data = (BookData*)(engine->engine_data); + + gchar* result; + if(data->auto_free) { + result = data->dict_path; + } + else { + result = g_strdup(data->dict_path); + } + + LOGS("Bookmark/%s->%s() returned string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_set_auto_free(engine, state) +void bm_engine_set_auto_free(Engine* engine, gboolean state) +{ + LOGS("Bookmark/%s->%s() called.\n" + "-->PARAM:engine at adress=%p\n" + "-->PARAM:state=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine, + PRINT_STATE(state) + ); + g_assert(engine != NULL); + BookData* data = (BookData*)(engine->engine_data); + + data->auto_free = state; + LOGS("Bookmark/%s->%s() Current auto_free is %s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + PRINT_STATE(data->auto_free) + ); +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_get_last_status(engine) +EngineStatus bm_engine_status(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called.\n" + "-->PARAM:engine at adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine + ); + BookData* data = (BookData*)(engine->engine_data); + LOGS("Bookmark/%s->%s() returned error code: %d\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (gint)(data->last_error) + ); + return data->last_error; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_set_progress_seed(engine, signal, val) +void bm_engine_set_progress_seed(Engine* engine, gchar* signal, gdouble seed) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + BookData* data = (BookData*)(engine->engine_data); + if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) { + data->cb_progress_caching_seed = seed; + LOGS("Bookmark/%s->%s() sets new seed=%0.2f for for signal " + "\"%s\".\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + seed, + signal + ); + } + else { + LOGS("Bookmark/%s->%s() unsupported signalfor progress: %s.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + }; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_set_callback(engine,signal,c_handler,data) +gpointer bm_engine_set_callback(Engine* engine, + gchar* signal, + gpointer c_handler, + gpointer user_data) +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + g_assert(engine != NULL); + g_assert(signal != NULL); + g_assert(c_handler != NULL); + BookData* data = (BookData*)(engine->engine_data); + if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) { + gpointer result = data->cb_progress_caching; + data->cb_progress_caching = c_handler; + data->cb_progress_caching_data = user_data; + LOGS("Bookmark/%s->%s() sets handler for signal \"%s\".\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + LOGS("Bookmark/%s->%s() Function at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)c_handler + ); + LOGS("Bookmark/%s->%s() Data at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)user_data + ); + return result; + } + else if(g_ascii_strcasecmp(signal, ENGINE_WORD_LIST_SIGNAL) == 0) { + gpointer result = data->cb_search_word_list; + data->cb_search_word_list = c_handler; + data->cb_search_word_list_data = user_data; + LOGS("Bookmark/%s->%s() sets handler for signal \"%s\".\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + LOGS("Bookmark/%s->%s() Function at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)c_handler + ); + LOGS("Bookmark/%s->%s() Data at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)user_data + ); + return result; + } + else if(g_ascii_strcasecmp(signal, + ENGINE_WORD_TRANSLATION_SIGNAL) == 0) { + gpointer result = data->cb_search_word_trans; + data->cb_search_word_trans = c_handler; + data->cb_search_word_trans_data = user_data; + LOGS("Bookmark/%s->%s() sets handler for signal \"%s\".\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + LOGS("Bookmark/%s->%s() Function at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)c_handler + ); + LOGS("Bookmark/%s->%s() Data at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)user_data + ); + return result; + } + else { + g_warning("Bookmark/%s->%s() unsupported signal: %s.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + return NULL; + } +} + + + + + + +//============================================================================== +//============================================================================== +//============================================================================== +//---------------------------------------------------------- HELPFULLY FUNCTIONS +//============================================================================== + +//------------------------------------------------------------------------------ +static gchar* string_to_path(gchar** string) { + LOGS("Bookmark/%s->%s() called.\n\ + -->PARAM:string=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + string[0] + ); + gchar* arg = string[0]; + gchar* new = NULL; + // cleaning from leading and trailing whitespaces + g_strstrip(arg); + // add current directory if this is not absolute directory + if (!g_path_is_absolute(arg)) { + gchar* tmp = g_get_current_dir(); + new = g_strconcat(tmp,"/",arg,NULL); + g_free(arg); arg = new; new = NULL; + }; + // this is not a directory + if (!g_file_test(arg, G_FILE_TEST_IS_DIR)) { + // if this is wrong filepath, string was wrong + if (!g_file_test(arg, G_FILE_TEST_IS_REGULAR)) { + g_free(arg); + new = NULL; + } + //if this is a file, remove filename + else + { + new = g_path_get_dirname (arg); + g_free(arg); + } + } + // this is a directory + else { + // remove suffix "/" if neded... + if (g_str_has_suffix(arg,"/") ) { + new = g_path_get_dirname (arg); + g_free(arg); + } + else { + new = arg; + } + }; + // now in new should be proper filepath, if not, string was wrong + if (!g_file_test(new, G_FILE_TEST_IS_DIR)) { + // if that directory does not exist, passed string wasn't proper + g_free(new); + new = NULL; + }; + // replace string under passed address + string[0] = new; + LOGS("Bookmark/%s->%s() returned string=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + string[0] + ); + return new; +} +//------------------------------------------------------------------------------ +static double timer(gboolean start, gchar* message) +{ + static GArray* stack = NULL; + static gboolean first_run = TRUE; + static struct timeval actual_time; + static struct timeval last_time; + static struct timeval result; + static double seconds = 0.0; + if(first_run) { + first_run = FALSE; + stack = g_array_new(TRUE, TRUE, sizeof(struct timeval)); + }; + + if (start) { + LOGS("Bookmark->%s() start timer for function '%s()'.\n", + (gchar*)__FUNCTION__, + message + ); + g_array_prepend_val(stack, actual_time); + gettimeofday(&g_array_index(stack, struct timeval, 0),NULL); + return -1.0; + } + // we just want to end some timer - print some information about + // working time; + else { + gettimeofday(&actual_time,NULL); + last_time = g_array_index(stack, struct timeval, 0); + g_array_remove_index(stack, 0); + + if (actual_time.tv_usec < last_time.tv_usec) { + int nsec = (last_time.tv_usec - actual_time.tv_usec) / + (1000000 + 1); + last_time.tv_usec -= 1000000 * nsec; + last_time.tv_sec += nsec; + } + if (actual_time.tv_usec - last_time.tv_usec > 1000000) { + int nsec = (last_time.tv_usec - actual_time.tv_usec) / + 1000000; + last_time.tv_usec += 1000000 * nsec; + last_time.tv_sec -= nsec; + } + result.tv_sec = actual_time.tv_sec - last_time.tv_sec; + result.tv_usec = actual_time.tv_usec - last_time.tv_usec; + seconds = (((double)(result.tv_usec)) / 1e6) + + ((double)(result.tv_sec)); + + LOGS("Bookmark->%s() function \'%s()\' was working for: %g " + "[s] or %ld [us].\n", + (gchar*)__FUNCTION__, + message, + seconds, + ((long)(result.tv_sec*1e6)+(result.tv_usec)) + ); + // stack is empty so we delete everything + if(stack->len == 0) + { + g_array_free(stack, TRUE); + first_run = TRUE; + } + } + return seconds; +} +//------------------------------------------------------------------------------ + + + diff --git a/src/bookmarks/sql3/src/test.c b/src/bookmarks/sql3/src/test.c new file mode 100644 index 0000000..b89a9a7 --- /dev/null +++ b/src/bookmarks/sql3/src/test.c @@ -0,0 +1,144 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#include +#include +#include +#include + + +getting_additional get_functions; // additinal functions for concrete module (e.g. XDXF) + +void print_list(GArray* list, gchar* pattern, gpointer user_data, EngineStatus error) { + printf((gchar*)user_data,pattern); + int i = 0; + while(g_array_index(list, gchar*, i) != NULL) + { + printf(" %d. : %s\n",i+1,g_array_index(list, gchar*, i)); + i++; + } + printf("--------------------------------------------------\n"); +} + +void print_translation(gchar* translation, gchar* word, gpointer user_data, EngineStatus error) { + printf((gchar*)user_data,word); + printf("%s\n\nTRANSLATION ENDS.\n",translation); +} + +void caching_progress(gdouble value, gpointer user_data, EngineStatus error) { + printf((gchar*)user_data,value); +} + +int main(int argc, char** argv) +{ + char* nameApp = "StarDictEngine test: "; + printf("%sStarting test program of module: dictionary_engine.\n",nameApp); + + + gchar* current_directory = g_get_current_dir(); + printf("%sCurrent directory: %s\n",nameApp,current_directory); + gchar* library_to_path = g_strconcat(current_directory, "/ws_bookmark.so", NULL); + printf("%sEngine library should be in location:\n\t%s\n",nameApp,library_to_path); + + GModule *library = g_module_open(library_to_path, G_MODULE_BIND_LAZY); + if(!library) { + printf("%sLoading module failed. \nReason: %s\n",nameApp,g_module_error()); + return 1; + }; + + //dict_eng_module_get_global_functions(library,get_functions); + g_module_symbol ( (library),_GLOBAL_FUNCTIONS_NAME_, (gpointer)&get_functions); + if(get_functions == NULL) { + printf("%sLoading function failed\n",nameApp); + return 2; + } + else printf("%sLoading function OK\n",nameApp); + + EngineModule module = get_functions(); + printf("Module description: %s\n",dict_eng_module_get_description(module)); + Engine* sd; + + gboolean is_compatible = dict_eng_module_check(module,"/home/str/whitestork/engines/bookmark/ws_bookmarks"); + if(is_compatible == TRUE) + { + printf("Location is compatible with enigne!\n"); + } + else { + printf("Location is not compatible with enigne!\n"); + return 1; + } + + //printf("%sCheck OK. Module description: %s\n", nameApp, dict_eng_module_get_description(module)); + + //xdxf = dict_eng_module_create_ext(module, "/home/lukasz/MyDocs/repo/WhiteStork/trunk/engine/bin" , ENGINE_CREATE, caching_progress, "Current progress of caching is: %0.2f.\n", 0.03 ); + //home/stranger/whitestork/engine0.2/ +// xdxf = dict_eng_module_create(module, "/home/stranger/whitestork/engine0.2/" , ENGINE_NO); +// dict_eng_set_callback(xdxf, ENGINE_PROGRESS_CACHING, caching_progress, "Current progress of caching is: %0.2f.\n"); +// dict_eng_set_progress_seed(xdxf, ENGINE_PROGRESS_CACHING, 0.02); + +/* if(dict_eng_is_optimized(xdxf) == FALSE) + { + printf("Dictionary has no cache!\nCreating cache file....\n"); + dict_eng_optimize(xdxf); + } + else { + printf("Dictionary has already cache file!\n"); + }*/ + sd = dict_eng_module_create(module, + "/home/str/whitestork/engines/bookmark/ws_bookmarks" , + ENGINE_CREATE); + printf("Lokacja: %s\n",dict_eng_get_location(sd)); + + dict_eng_set_callback(sd, + ENGINE_WORD_LIST_SIGNAL, + print_list, + "Word list matches to pattern: %s\n" + ); + dict_eng_set_callback(sd, + ENGINE_WORD_TRANSLATION_SIGNAL , + print_translation, + "Translation for word\'%s\':\n"); + + dict_eng_search_word_list(sd,"12"); + //dict_eng_search_word_translation(sd,"1 word"); + + dict_eng_remove_word(sd, "stranger"); + dict_eng_remove_word(sd, "gandzia"); + dict_eng_remove_word(sd, "lukas"); + dict_eng_add_word(sd, "stranger", "autor pluginu tego wlasnie to jest!"); + dict_eng_add_word(sd, "gandzia", "rulez"); + dict_eng_add_word(sd, "lukas", "pawlik"); + dict_eng_remove_word(sd, "stranger"); + + dict_eng_search_word_translation(sd,"stranger"); + + dict_eng_add_word(sd, "stranger", "autor pluginu tego wlasnie to jest!"); + dict_eng_search_word_translation(sd,"stranger"); + dict_eng_search_word_list(sd,"gandzia"); + + printf("Lang FROM:%s\n",dict_eng_get_lang_from(sd)); + printf(" Lang TO:%s\n",dict_eng_get_lang_to(sd)); + printf(" Title:%s\n",dict_eng_get_title(sd)); + printf("Icon path:%s\n",dict_eng_get_icon_path(sd)); + + dict_eng_destroy(sd); + printf("%sClosed.\n",nameApp); + return 0; +} + diff --git a/src/bookmarks/sql3/src/testMakeDatabase.c b/src/bookmarks/sql3/src/testMakeDatabase.c new file mode 100644 index 0000000..7ca65e1 --- /dev/null +++ b/src/bookmarks/sql3/src/testMakeDatabase.c @@ -0,0 +1,135 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ + +#include +#include +#include + +const guint records_number = 1000; + +// ---------------------------------------------------------------------------------- +sqlite* database_make(gchar* path) { + gchar* buffer = NULL; + sqlite* result = NULL; + // creatingh database + result = sqlite_open(path, + 0600, + &buffer); + // check if everything was okey + if(!result) { + g_printf("Error while trying to create database:\n%s\n",buffer); + g_free(buffer); buffer = NULL; + return NULL; + }; + // return pointer to database + return result; +} +// ---------------------------------------------------------------------------------- +gint database_add_test_table(sqlite* db) { + gint result = 0; + //gchar sql[] = "CREATE TABLE words(id INTEGER PRIMARY KEY, word TEXT UNIQUE);"; + gchar sql2[] = "CREATE TABLE translations(id INTEGER PRIMARY KEY, word TEXT, translation TEXT);"; + gchar* err = NULL; +/* + result = sqlite_exec(db, sql, NULL, NULL, &err); + if(err || result!=0) { + g_printf("Error while creating \'words\' table:\n%s\n",err); + return 1; + } +*/ + result = sqlite_exec(db, sql2, NULL, NULL, &err); + if(err || result!=0) { + g_printf("Error while creating \'translations\' table:\n%s\n",err); + return 2; + } + + return result; +} +// ---------------------------------------------------------------------------------- +gint database_add_test_record(sqlite* db, guint i) { + gint result = 0; + gchar* sql = NULL; + gchar* err = NULL; + gint last_id = 0; + gint word_count = 1; + gchar buffer[] = " "; + gchar last_char[] = " "; + gchar tran[] = "this is a translation number 10.000 for word 10.000 word <-----"; + g_sprintf(buffer,"%d word",i); +/* + sql = g_strconcat("INSERT INTO words VALUES(NULL,\'",buffer,"\');", NULL); + result = sqlite_exec(db, sql, NULL, NULL, &err); + if(err || result!=0) { + g_printf("Error while trying to add new word %d:\n%s\n",i,err); + g_free(sql); + return 1; + } + g_free(sql); + last_id = sqlite_last_insert_rowid(db); + g_sprintf(last_char,"%d",last_id); +*/ + if(i == 5000) { + word_count = 5; + g_printf("Adding more records for word - test\n"); + } + gint j; + for(j=0; j + Copyright (C) + + 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. + +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. + + , 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 Lesser General +Public License instead of this License. \ No newline at end of file diff --git a/src/bookmarks/xdxf/Makefile b/src/bookmarks/xdxf/Makefile new file mode 100644 index 0000000..aeb665e --- /dev/null +++ b/src/bookmarks/xdxf/Makefile @@ -0,0 +1,44 @@ +COMPILER = gcc +DEBUG = -Wall -g +SOURCES = ./src +INCLUDE = include +INCLUDE_ENGINE = ../../../include +LIBS = `pkg-config --libs glib-2.0 gmodule-2.0 gnome-vfs-2.0` +FLAGS = `pkg-config --cflags glib-2.0 gmodule-2.0 gnome-vfs-2.0` -I${INCLUDE} -I${INCLUDE_ENGINE} ${DEBUG} +BINARIES = bin +FINAL = ../../../bin/ws_bookmark.so + + +${FINAL}: ${BINARIES}/bookmark.o ${SOURCES}/engine_bookmark.c + @gcc -shared -fPIC ${FLAGS} ${LIBS} ${BINARIES}/bookmark.o -o ${FINAL} + +${BINARIES}/bookmark.o: ${SOURCES}/engine_bookmark.c + @gcc -c -fPIC -o ${BINARIES}/bookmark.o ${SOURCES}/engine_bookmark.c ${FLAGS} + +clean: + @-rm -f ${BINARIES}/* + @-rm -f ${FINAL} + @echo -e -n "Project's 'BookmarkEngine' directories has been cleaned.\n" + +cleandata: + @-rm -f ws_bookmarks-journal + @-rm -f ws_bookmarks + + +data: ${SOURCES}/testMakeDatabase.c + @echo -e -n "Compiling testDatabase...\n" + @gcc -o ${SOURCES}/testDatabase ${SOURCES}/testMakeDatabase.c ${FLAGS} ${LIBS} + +datarun: data + @run-standalone.sh src/testDatabase + +test: + @echo "Linking test program..." + @gcc ${LIBS} ${DEBUG} ${SOURCES}/test.c -o ${BINARIES}/test ${FLAGS} + @echo -e "Building test program finished.\n" + +check: + @echo "Running test program:" + @run-standalone.sh ${SOURCES}/test + + \ No newline at end of file diff --git a/src/bookmarks/xdxf/include/engine_bookmark.h b/src/bookmarks/xdxf/include/engine_bookmark.h new file mode 100644 index 0000000..285cc2a --- /dev/null +++ b/src/bookmarks/xdxf/include/engine_bookmark.h @@ -0,0 +1,326 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#ifndef _DICTIONARY__XDXF +#define _DICTIONARY_ENGINE_XDXF + +#ifdef __cplusplus + extern "C" { +#endif + +//______________________________________________________________________________ +// ***************************************************************************** +//************************************************************* HEADERS SECTION: +//------------------------------------------------------------------------------ +// headers with unix types/functions - onl for timers +#include +#include +#include +#include +#include +//------------------------------------------------------------------------------ +// header with GLIB definitions/functions/types +#include +//------------------------------------------------------------------------------ +// header with gnome-vfs - recommended I/O API for maemo +#include +//------------------------------------------------------------------------------ +// header with expat - XML Parser API +#include +//------------------------------------------------------------------------------ +// header wit engine API +#include +//------------------------------------------------------------------------------ +#include + + +//______________________________________________________________________________ +// ***************************************************************************** +//********************************************************* DEFINITIONS SECTION: +//------------------------------------------------------------------------------ +// definitions for timer function - flag telling if we want to start or stop +// timing +#define TIMER_START TRUE +#define TIMER_STOP FALSE +//------------------------------------------------------------------------------ +// definitions of version and format which engine handles +static const gchar* DIC_ENG_VERSION = "0.1"; +static const gchar* DIC_ENG_FORMAT = "Users' Bookmarks"; +static const gchar* DIC_ENG_DESCRIPTION = "This module handles users' bookmarks."; +//------------------------------------------------------------------------------ +// defines lenght of buffers for particular functions in engine which needs +// big buffers +#define DICT_CACHEING_BUFF_SIZE 16*1024 +#define DICT_SEARCHING_WORD_LIST_BUFF_SIZE 16*1024 +#define DICT_SEARCHING_WORD_TRAN_BUFF_SIZE 16*1024 +//------------------------------------------------------------------------------ +// maximum length of word possible to find in any dictionary +#define DICT_MAX_WORD_LENGTH 512 +//------------------------------------------------------------------------------ +// macro for "printing" gboolean statement - "TRUE" or "FALSE" +#define PRINT_STATE(state) ( (state) ? "TRUE" : "FALSE" ) +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//****************************************** DATA STRUCTURE DEFINITIONS SECTION: +//------------------------------------------------------------------------------ +/** \brief Structure used while dict_eng_module_check() is working. + */ +struct _XDXFCheckingData { + gboolean further; + gboolean good; + guint deep; +}; +typedef struct _XDXFCheckingData XDXFCheckingData; +//------------------------------------------------------------------------------ +/** \brief Structure to help parse xdxf file for searching words list. + */ +struct _XDXFWordsListData { + gchar* last_word; + gchar* pattern; + guint pattern_len; + guint last_word_length; + GArray* result; + guint one_word; + gboolean cont; +}; +typedef struct _XDXFWordsListData XDXFWordsListData; +//------------------------------------------------------------------------------ +/** \brief Structure to help parse xdxf file for searching word's translation. + */ +struct _XDXFWordsTransData { + gchar* last_word; + gchar* word; + guint word_len; + guint last_word_length; + gchar* translation; + guint one_word; + gboolean cont; + gulong last_start; + XML_Parser* parser; + gboolean found; + GnomeVFSHandle* xdxf; +}; +typedef struct _XDXFWordsTransData XDXFWordsTransData; +//------------------------------------------------------------------------------ +/** \brief Structure to help make optimization possible + */ +struct _XDXFCacheData { + gchar* buffer; + long last_start; + long last_stop; + long last_length; + GnomeVFSHandle* cache; + XML_Parser parser; + int state; + long buffer_length; +}; +typedef struct _XDXFCacheData XDXFCacheData; +//------------------------------------------------------------------------------ +/** \brief Internal data structure for representing part of file. + */ +struct _FilePart { + guint offset; + guint length; +}; +typedef struct _FilePart FilePart; +//------------------------------------------------------------------------------ +/** \brief Internal data structure of XDXF Engine. + */ +struct _XDXFData { + GnomeVFSHandle* xdxf; + GnomeVFSHandle* cache; + gchar* dict_path; + EngineStatus last_error; + gboolean auto_free; + + cb_progress cb_progress_caching; + gpointer cb_progress_caching_data; + gdouble cb_progress_caching_seed; + + cb_progress cb_progress_word_list; + gpointer cb_progress_word_list_data; + gdouble cb_progress_word_list_seed; + + cb_progress cb_progress_word_trans; + gpointer cb_progress_word_trans_data; + gdouble cb_progress_word_trans_seed; + + cb_word_list cb_search_word_list; + gpointer cb_search_word_list_data; + + cb_word_translation cb_search_word_trans; + gpointer cb_search_word_trans_data; +}; +typedef struct _XDXFData XDXFData; +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//*************************************************** PARSING FUNCTIONS SECTION: +//------------------------------------------------------------------------------ +// while is_bm_file() is working +static void is_bm_file_start(void *data, + const char *el, + const char **attr); +static void is_bm_file_end(void *data, const char *el); +//------------------------------------------------------------------------------ +// while dict_eng_search_word_list() is working +static void search_word_list_start(void *data, + const char *el, + const char **attr); +static void search_word_list_end(void *data, const char *el); +static void search_word_list_text(void *data, const XML_Char *txt, int len); +//------------------------------------------------------------------------------ +// // while dict_eng_search_word_translation() is working +static void search_word_trans_start(void *data, + const char *el, + const char **attr); +static void search_word_trans_end(void *data, const char *el); +static void search_word_trans_text(void *data, + const XML_Char *txt, + int len); +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//************************************************ ADDITIONAL FUNCTIONS SECTION: +//------------------------------------------------------------------------------ +// returning concrete part of file +static gchar* read_file_part(FilePart* part, GnomeVFSHandle* file); +//------------------------------------------------------------------------------ +//convert string to proper path name (no filename, no "/" at the ned, file exist) +static gchar* string_to_path(gchar** string); +//------------------------------------------------------------------------------ +// tells if file is in XDXF format (file should exist) +static gboolean is_bm_file(gchar* file); +//------------------------------------------------------------------------------ +// start/stop timers - returnet -1.0 if we start or seconds passed from start +// if we want to stop timer +static double timer(gboolean start, gchar* message); +//------------------------------------------------------------------------------ +// return size of files +static guint64 get_file_size(GnomeVFSHandle* file); +//------------------------------------------------------------------------------ +// return how many records (from cache file) are in current buffer a with length +// length. +static guint get_max_length(gchar* a, guint length); +//------------------------------------------------------------------------------ +// return translation of word using cache file +static gchar* word_translation_cache(XDXFData* data, gchar* word); +//------------------------------------------------------------------------------ +// return translation of word but using only xdxf dictionary file +static gchar* word_translation_xdxf(XDXFData* data, gchar* word); +//------------------------------------------------------------------------------ + +// return translation of word using cache file +static void word_list_cache(XDXFData* data, gchar* pattern, GArray* result); +//------------------------------------------------------------------------------ +// return translation of word but using only xdxf dictionary file +static void word_list_xdxf(XDXFData* data, gchar* pattern, GArray* result); +//------------------------------------------------------------------------------ + + + +//______________________________________________________________________________ +// ***************************************************************************** +//****************************************************** MAIN FUNCTIONS SECTION: +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_check(module,location) function +gboolean bm_engine_check(gchar* location); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_get_description(module) function +gchar* bm_engine_description(); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_get_format(module) function +gchar* bm_engine_format(); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_get_version(module) function +gchar* bm_engine_version(); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_create(module,location,flags) and +// dict_eng_module_create_ext(module,location,flags) functions +Engine* bm_engine_create(gchar* location, + EngineOptimizationFlag flags, + cb_progress progress_handler, + gpointer progress_data, + gdouble seed); +//------------------------------------------------------------------------------ +// implementation of dict_eng_destroy(engine) function +void bm_engine_close(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_get_location(engine) function +gchar* bm_engine_location(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_optimize(engine) function +void bm_engine_optimize(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_is_optimized( engine ) function +gboolean bm_engine_is_optimized(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_set_auto_free(engine, state) function +void bm_engine_set_auto_free(Engine* engine, gboolean state); +//------------------------------------------------------------------------------ +// implementation of dict_eng_set_callback(engine,signal,c_handler,data) +// function +gpointer bm_engine_set_callbacks(Engine* engine, + gchar* event, + gpointer c_handler, + gpointer user_data); +//------------------------------------------------------------------------------ +// implementation of dict_eng_set_progress_seed(engine, signal, val) function +void bm_engine_set_progress_seed(Engine* engine, + gchar* signal, + gdouble seed); +//------------------------------------------------------------------------------ +// implementation ofdict_eng_search_word_list(engine,pattern) function +void bm_engine_search_word_list(Engine* engine, gchar* pattern); +//------------------------------------------------------------------------------ +// implementation of dict_eng_search_word_translation(engine,word) function +void bm_engine_search_word_translation(Engine* engine, gchar* word); +//------------------------------------------------------------------------------ +// implementation of dict_eng_search_word_translation_extended(engine,word) +// function +void bm_engine_search_word_translation_extended(Engine* engine, + gchar* word); +//------------------------------------------------------------------------------ +// implementation of dict_eng_get_last_state(engine) function +EngineStatus bm_engine_error(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_state_message(error) function +gchar* bm_engine_error_message(EngineStatus error); +//------------------------------------------------------------------------------ +// implementation of engine_global_functions(void) function +// API 2.0 +gboolean bm_engine_add_word(Engine* engine, + gchar* word, + gchar* translation); + +gboolean bm_engine_remove_word(Engine* engine, gchar* word); + +EngineModule engine_global_functions(); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/bookmarks/xdxf/src/engine_bookmark.c b/src/bookmarks/xdxf/src/engine_bookmark.c new file mode 100644 index 0000000..4800ab2 --- /dev/null +++ b/src/bookmarks/xdxf/src/engine_bookmark.c @@ -0,0 +1,1995 @@ +/****************************************************************************** +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +******************************************************************************/ + +// header with data structure and function definition for XDXF engine. +// Also Engine API. +#include +#include +//------------------------------------------------------------------------------ +#define LOGS g_debug +#define g_strlen(string) ( NULL == (string) ? 0 : strlen(string) ) +// searching word translation in cache file +static void caching_expat_start(void *data, const char *el, const char **attr); +static void caching_expat_end(void *data, const char *el); +static void caching_expat_text(void *data, const XML_Char *txt, int len); +static gchar* word_translation_cache(XDXFData* data, gchar* word) +{ + gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 0); + gchar b[DICT_SEARCHING_WORD_TRAN_BUFF_SIZE + 1]; + GnomeVFSFileSize bytes_readed; + + guint word_length = g_strlen(word); + guint record_length = 0; + guint trans_offset = 0; + guint already = 0; + guint64 readed = 0; + gchar* buffer = NULL; + gchar* trans = NULL; + guint file_size = get_file_size(data->cache); + if (file_size > 0){ + while(TRUE) { + gnome_vfs_read(data->cache, + b, + DICT_SEARCHING_WORD_TRAN_BUFF_SIZE, + &bytes_readed + ); + guint max_length = (guint)get_max_length(b,bytes_readed); + readed += max_length; + buffer = b; + already = 0; + while(already < max_length) { + memcpy(&record_length, buffer, sizeof(guint)); + memcpy(&trans_offset, + buffer+record_length-2*sizeof(guint), + sizeof(guint) + ); + buffer[record_length-sizeof(guint)*2] = '\0'; + if(((record_length - 3*sizeof(guint)) == word_length) && + (g_utf8_collate(word,buffer+sizeof(guint)) == 0)) { + FilePart translation = {0,0}; + translation.offset = trans_offset; + memcpy(&(translation.length), + buffer + record_length - sizeof(guint), + sizeof(guint) + ); + trans =read_file_part(&translation, data->xdxf); + break; + }; + already += record_length; + buffer += record_length; + }; + + if( ( bytes_readed < DICT_SEARCHING_WORD_TRAN_BUFF_SIZE ) || + ( readed > (file_size - 3) )) { + break; + }; + gnome_vfs_seek(data->cache, + GNOME_VFS_SEEK_CURRENT, + ((gint)max_length) - + DICT_SEARCHING_WORD_TRAN_BUFF_SIZE + ); + } + } + return trans; +} +//------------------------------------------------------------------------------ +// searching word translation in xdxf dictionary +static gchar* word_translation_xdxf(XDXFData* data, gchar* word) { + guint word_length = strlen(word); + gchar* trans = NULL; + gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, 0); + GnomeVFSResult vfs_result; + GnomeVFSFileSize bytes_readed = DICT_SEARCHING_WORD_TRAN_BUFF_SIZE; + gchar buffer[DICT_SEARCHING_WORD_TRAN_BUFF_SIZE+1]; + guint64 file_size = get_file_size(data->xdxf); + //guint word_len = strlen(word); added by me + + XML_Parser parser = XML_ParserCreate(NULL); + if (!parser) { + g_warning("%s->%s() Could not open initialize " + "XML parser.\n", + __FILE__, + __FUNCTION__ + ); + timer(TIMER_STOP,(gchar*)__FUNCTION__); + return NULL; + }; + + gchar tmp[DICT_MAX_WORD_LENGTH]; + XDXFWordsTransData search_data = {tmp, + word, + word_length, + 0, + NULL, + FALSE, + TRUE, + 0, + &parser, + FALSE, + data->xdxf + }; + XML_SetElementHandler(parser, + search_word_trans_start, + search_word_trans_end + ); + XML_SetCharacterDataHandler(parser, search_word_trans_text); + + XML_SetUserData(parser, &search_data); + + //gdouble last_prog = 0; + while(TRUE) { + vfs_result = gnome_vfs_read(data->xdxf, + buffer, + DICT_SEARCHING_WORD_TRAN_BUFF_SIZE, + &bytes_readed + ); + XML_Parse(parser, + buffer, + bytes_readed, + bytes_readed < DICT_SEARCHING_WORD_TRAN_BUFF_SIZE + ); + + gdouble last_prog = 0.0; + if(data->cb_progress_word_trans != NULL) { + GnomeVFSFileSize act_pos; + gnome_vfs_tell(data->xdxf, &act_pos); + gdouble progress = + ((gdouble)act_pos)/((gdouble)file_size); + if((( (progress - last_prog)/ + (data->cb_progress_word_trans_seed) ) > 1.0) || + (progress >= 1.0)) { + data-> + cb_progress_word_trans(progress, + data->cb_progress_word_trans_data, + ENGINE_NO_ERROR + ); + last_prog = progress; + }; + } + if(bytes_readed < DICT_SEARCHING_WORD_TRAN_BUFF_SIZE) { + break; + } + if(search_data.cont == FALSE) { + break; + } + } + XML_ParserFree(parser); + trans = search_data.translation; + return trans; +} + +//------------------------------------------------------------------------------ +// get position of a word in order to add this word to bookmarks +/*GnomeVFSFileSize*/ +static FilePart get_adding_position(XDXFData* data, + gchar* word) +{ + + + g_debug("%s<->", __FUNCTION__); + gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 0); + gchar b[DICT_SEARCHING_WORD_TRAN_BUFF_SIZE + 1]; + GnomeVFSFileSize bytes_readed; + + //guint word_length = g_strlen(word); + guint record_length = 0; + guint trans_offset = 0; + guint already = 0; + guint64 readed = 0; + gchar* buffer = NULL; + gchar* trans = NULL; + +// g_printf ("\n\ncache: %p\n", data->cache); + +// return 0; + gchar* down_word = g_utf8_strdown(word, -1); + guint file_size = get_file_size(data->cache); + if (file_size > 0){ + while(TRUE) { + gnome_vfs_read(data->cache, + b, + DICT_SEARCHING_WORD_TRAN_BUFF_SIZE, + &bytes_readed + ); + guint max_length = (guint)get_max_length(b,bytes_readed); + readed += max_length; + buffer = b; + already = 0; + while(already < max_length) { + memcpy(&record_length, buffer, sizeof(guint)); + memcpy(&trans_offset, + buffer+record_length-2*sizeof(guint), + sizeof(guint) + ); + buffer[record_length-sizeof(guint)*2] = '\0'; + gboolean test = + g_utf8_collate(buffer+sizeof(guint), down_word); + g_debug("And here is the buffer content: %s\nCompare result of word %d which is %s", + buffer+sizeof(guint), test, down_word); + if(/*((record_length - 3*sizeof(guint)) == word_length) &&*/ + test >= 0) + { + FilePart translation = {0,0}; + translation.offset = trans_offset; + memcpy(&(translation.length), + buffer + record_length - sizeof(guint), + sizeof(guint) + ); + trans =read_file_part(&translation, data->xdxf); + return translation/*translation.offset + translation.length*/; + + }; + already += record_length; + buffer += record_length; + }; + + if( ( bytes_readed < DICT_SEARCHING_WORD_TRAN_BUFF_SIZE ) || + ( readed > (file_size - 3) )) { + break; + }; + gnome_vfs_seek(data->cache, + GNOME_VFS_SEEK_CURRENT, + ((gint)max_length) - + DICT_SEARCHING_WORD_TRAN_BUFF_SIZE + ); + } + } + guint64 tmp_offset = get_file_size(data->xdxf) - g_strlen(""); + //g_debug("TMP_OFFSET: %ld", tmp_offset); + FilePart translation = {tmp_offset,0}; + return /*trans_offset*/translation; +} + +//------------------------------------------------------------------------------ +// searching word by concrete engine +void bm_engine_search_word_translation(Engine* engine, gchar* word) +{ + g_debug("%s->%s() called.\n" + "-->PARAM:engine at adress=%p\n" + "-->PARAM:word=\'%s\'\n", + __FILE__, + __FUNCTION__, + engine, + word); + g_assert(engine != NULL); + g_assert(word != NULL); + // start timer for this function + timer(TIMER_START, (gchar*)__FUNCTION__); + XDXFData* data = (XDXFData*)(engine->engine_data); + // if callback is not set, we do not have to search word + if(data->cb_search_word_trans == NULL) { + g_warning("%s->%s() callback for Word Translation not set." + " Searching aborted.\n", + __FILE__, + __FUNCTION__ + ); + timer(TIMER_STOP,(gchar*)__FUNCTION__); + // do not send any signal, just exit + return; + }; + + //guint word_length = strlen(word); + gchar* trans; + + // dictionary is optimized + if(data->cache != NULL) { + trans = word_translation_cache(data, word); + // dictionary is not optimized right now + } else + { + trans = word_translation_xdxf(data, word); + }; + + g_debug("%s->%s() found for word \'%s\' translation:\n\'%s\'\n", + __FILE__, + __FUNCTION__, + word, + trans + ); + timer(TIMER_STOP,(gchar*)__FUNCTION__); + timer(TIMER_START,"callback for returning word's translation START"); + // calling callback for word translation + data->cb_search_word_trans(trans, + word, + data->cb_search_word_trans_data, + ENGINE_NO_ERROR + ); + timer(TIMER_STOP,"callback for returning word's translation END"); + if(data->auto_free) { + g_debug("%s->%s() deleting all dynamic data because " + "AUTO_FREE=TRUE\n", + __FILE__, + __FUNCTION__ + ); + g_free(trans); + } + trans = NULL; + return; +} +//------------------------------------------------------------------------------ +gboolean bm_engine_remove_word(Engine* engine, + gchar* word) +{ + g_debug("%s <-> %s()", __FILE__, __FUNCTION__); + GnomeVFSResult vfs_result; + XDXFData* data = (XDXFData*)(engine->engine_data); + GnomeVFSHandle* swap_xdxf; + vfs_result = + gnome_vfs_create(&(swap_xdxf), "/media/mmc1/swap_xdxf.xdxf", + GNOME_VFS_OPEN_WRITE | + GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_RANDOM, + FALSE, 0666); + if(vfs_result != GNOME_VFS_OK) { + g_warning("%s->%s() opening dictionary file failed" + " due to reason: %s.\n", + __FILE__, + __FUNCTION__, + gnome_vfs_result_to_string(vfs_result) + ); + return FALSE; + } + + FilePart position_part = get_adding_position (data, word); + //GnomeVFSFileSize position = position_part.offset /*+ position_part.length*/; + //guint64 file_size = get_file_size(data->cache); + gchar read_buffer[DICT_CACHEING_BUFF_SIZE + 1]; + GnomeVFSFileSize read_size = DICT_CACHEING_BUFF_SIZE; + GnomeVFSFileSize read_bytes_size = DICT_CACHEING_BUFF_SIZE; + GnomeVFSFileSize bytes_written; + gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, + position_part.offset + position_part.length); + /*Write form position to the end of the file*/ +// GnomeVFSFileSize position = position_part.offset + + while(TRUE) + { + g_debug(":Working around in writing the tail:"); + + gnome_vfs_read(data->xdxf/*GnomeVFSHandle */, + read_buffer/*buffer*/, + read_size/*GnomeVFSFileSize*/, + &read_bytes_size/*GnomeVFSFileSize*/); + g_debug("%s", gnome_vfs_result_to_string(vfs_result)); + vfs_result = gnome_vfs_write(swap_xdxf, + read_buffer, + read_bytes_size, + &bytes_written); + g_debug("%s", gnome_vfs_result_to_string(vfs_result)); + if (read_bytes_size < DICT_CACHEING_BUFF_SIZE) break; + } + + //g_printf (">>> %s %d %s<<<\n", word, position, data->dict_path); + //gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, position_part.offset); + + gnome_vfs_truncate_handle(data->xdxf, position_part.offset); + + read_bytes_size = DICT_CACHEING_BUFF_SIZE; + read_size = DICT_CACHEING_BUFF_SIZE + 1 ; + //bytes_written = DICT_CACHEING_BUFF_SIZE; + gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, position_part.offset); + gnome_vfs_seek(swap_xdxf, GNOME_VFS_SEEK_START, 0); + while(TRUE) + { + g_debug(":Working around in writing back the tail:"); + + gnome_vfs_read(swap_xdxf/*GnomeVFSHandle */, + read_buffer/*buffer*/, + read_size/*GnomeVFSFileSize*/, + &read_bytes_size/*GnomeVFSFileSize*/); + g_debug("%s", gnome_vfs_result_to_string(vfs_result)); + vfs_result = gnome_vfs_write(data->xdxf, + read_buffer, + read_bytes_size, + &bytes_written); + g_debug("%s", gnome_vfs_result_to_string(vfs_result)); +// g_return_val_if_fail(vfs_result != GNOME_VFS_OK, FALSE); + if (read_bytes_size < DICT_CACHEING_BUFF_SIZE) break; + } + gnome_vfs_close(swap_xdxf); + gnome_vfs_unlink("/media/mmc1/swap_xdxf.xdxf"); + gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, + 0); + gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, + 0); + gnome_vfs_close(data->cache); + gchar* cache_path = g_strconcat(data->dict_path, "/ws_bookmarks.cache", NULL); + gnome_vfs_unlink(cache_path); + bm_engine_optimize(engine); + g_free(cache_path); + return TRUE; +} + +gboolean bm_engine_add_word(Engine* engine, + gchar* word, + gchar* translation) +{ + g_debug("%s -> %s()", __FILE__, __FUNCTION__); + + //guint word_length = strlen(word); + XDXFData* data = (XDXFData*)(engine->engine_data); + GnomeVFSResult vfs_result; + GnomeVFSHandle* swap_xdxf; + vfs_result = + gnome_vfs_create(&(swap_xdxf), "/media/mmc1/swap_xdxf.xdxf", + GNOME_VFS_OPEN_WRITE | + GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_RANDOM, + FALSE, 0666); + if(vfs_result != GNOME_VFS_OK) { + g_warning("%s->%s() opening dictionary file failed" + " due to reason: %s.\n", + __FILE__, + __FUNCTION__, + gnome_vfs_result_to_string(vfs_result) + ); + return FALSE; + } + + +// guint64 file_size = get_file_size(data->xdxf); + FilePart position_part = get_adding_position(data, word); + GnomeVFSFileSize position = + position_part.offset/* + position_part.length*/; + gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, + position); + gchar read_buffer[DICT_CACHEING_BUFF_SIZE + 1]; + GnomeVFSFileSize read_size = DICT_CACHEING_BUFF_SIZE + 1 ; + GnomeVFSFileSize read_bytes_size = DICT_CACHEING_BUFF_SIZE; + GnomeVFSFileSize bytes_written; + /*Write form position to the end of the file*/ + while(TRUE) + { + g_debug(":Working around in writing the tail:"); + + vfs_result = gnome_vfs_read(data->xdxf/*GnomeVFSHandle */, + read_buffer/*buffer*/, + read_size/*GnomeVFSFileSize*/, + &read_bytes_size/*GnomeVFSFileSize*/); + g_debug("%s", gnome_vfs_result_to_string(vfs_result)); + //g_return_val_if_fail(vfs_result != GNOME_VFS_OK, FALSE); + vfs_result = gnome_vfs_write(swap_xdxf, + read_buffer, + read_bytes_size, + &bytes_written); + g_debug("%s", gnome_vfs_result_to_string(vfs_result)); + //g_return_val_if_fail(vfs_result != GNOME_VFS_OK, FALSE); + if (read_bytes_size < DICT_CACHEING_BUFF_SIZE) break; + } + /*End write*/ + /*Write new entry*/ + /*gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, + position);*/ + gchar* buffer = NULL; + /*Testing if the adding word is in bookmark file*/ + gchar* search_pattern = g_strconcat("", word, "", NULL); + //gint search_pattern_len = g_strlen(search_pattern); + gchar read_word[position_part.length + 1]; + gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, + position_part.offset); + gnome_vfs_read(data->xdxf/*GnomeVFSHandle */, + read_word/*buffer*/, + position_part.length/*GnomeVFSFileSize*/, + &read_bytes_size/*GnomeVFSFileSize*/); + gchar* cmp_result = g_strrstr(read_word /*haystack*/, + search_pattern/*needle*/); + if (cmp_result != NULL) + { + + gchar** tmp = g_strsplit(translation, + "", + 2); + gchar* tmp2 = g_strndup(tmp[1], + g_strlen(tmp[1]) - g_strlen("")); + gchar* tmp3 = g_strndup(read_word, + g_strlen(read_word) - g_strlen("")); + buffer = g_strconcat(tmp3, tmp2, "", NULL); + g_strfreev(tmp); + g_free(tmp2); + g_free(tmp3); + gnome_vfs_seek(swap_xdxf, GNOME_VFS_SEEK_START, + position_part.length); + }else + { + buffer = g_strdup(translation); + gnome_vfs_seek(swap_xdxf, GNOME_VFS_SEEK_START, 0); + } + /*End of testing*/ + gnome_vfs_truncate_handle(data->xdxf, position_part.offset); + gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_END, 0); + GnomeVFSFileSize buffer_size = g_strlen(buffer); + + gnome_vfs_write(data->xdxf, + buffer, + buffer_size, + &bytes_written + ); + + read_bytes_size = DICT_CACHEING_BUFF_SIZE; + read_size = DICT_CACHEING_BUFF_SIZE + 1 ; + //bytes_written = DICT_CACHEING_BUFF_SIZE; + //gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, 0); + while(TRUE) + { + + + vfs_result = gnome_vfs_read(swap_xdxf/*GnomeVFSHandle */, + read_buffer/*buffer*/, + read_size/*GnomeVFSFileSize*/, + &read_bytes_size/*GnomeVFSFileSize*/); + g_debug("%s", gnome_vfs_result_to_string(vfs_result)); + vfs_result = gnome_vfs_write(data->xdxf, + read_buffer, + read_bytes_size, + &bytes_written); + //g_return_val_if_fail(vfs_result != GNOME_VFS_OK, FALSE); + g_debug("%s", gnome_vfs_result_to_string(vfs_result)); + //g_debug("%d", bytes_written); + if (read_bytes_size < DICT_CACHEING_BUFF_SIZE) break; + } + /*End write back*/ + + gnome_vfs_close(swap_xdxf); + gnome_vfs_unlink("/media/mmc1/swap_xdxf.xdxf"); +// gnome_vfs_close(data->xdxf); +// gnome_vfs_open(data->xdxf, data->dict_path, GNOME_VFS_OPEN_READ); + gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, + 0); + gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, + 0); + gnome_vfs_close(data->cache); + gchar* cache_path = g_strconcat(data->dict_path, "/ws_bookmarks.cache", NULL); + //gnome_vfs_unlink(cache_path); + bm_engine_optimize(engine); + g_free(cache_path); + return TRUE; +} + +static void search_word_trans_start(void *data, + const char *el, + const char **attr + ) +{ + XDXFWordsTransData* loc_data = (XDXFWordsTransData*)data; + if((loc_data->translation != NULL) || !(loc_data->cont)) { + return; + }; + + if(g_utf8_collate(el,"k") == 0) { + loc_data->one_word = 1; + } else if(g_utf8_collate(el,"ar") == 0) { + loc_data->last_start = + XML_GetCurrentByteIndex(*(loc_data->parser)); + } +} +//------------------------------------------------------------------------------ +static void search_word_trans_end(void *data, const char *el) +{ + XDXFWordsTransData* loc_data = (XDXFWordsTransData*)data; + if((loc_data->translation != NULL) || !(loc_data->cont)) { + return; + }; + + if(g_utf8_collate(el,"k") == 0) { + loc_data->one_word = 0; + + gint com = g_utf8_collate(loc_data->last_word, loc_data->word); + if(com > 0) { + loc_data->cont = FALSE; + return; + } else if((loc_data->last_word_length == loc_data->word_len) && + ( com == 0 ) + ) { + loc_data->found = TRUE; + }; + // "clearing" buffer for next word + loc_data->last_word_length = 0; + } + else if((g_utf8_collate(el,"ar") == 0) && (loc_data->found)) { + loc_data->found = FALSE; + loc_data->cont = FALSE; + gulong last_stop = + (gulong)XML_GetCurrentByteIndex(*(loc_data->parser)); + last_stop += strlen(""); + FilePart fp = {loc_data->last_start, + (last_stop - (loc_data->last_start)) + }; + loc_data->translation = read_file_part(&fp, loc_data->xdxf); + } +} +//------------------------------------------------------------------------------ +static void search_word_trans_text(void *data, const XML_Char *txt, int len) +{ + XDXFWordsTransData* loc_data = (XDXFWordsTransData*)data; + if((loc_data->translation != NULL) || !(loc_data->cont)) { + return; + }; + + if(loc_data->one_word == 1) { + memcpy(&(loc_data->last_word[loc_data->last_word_length]), + (gchar*)txt, + len + ); + loc_data->last_word_length += (guint)len; + loc_data->last_word[loc_data->last_word_length] = '\0'; + }; +} +//------------------------------------------------------------------------------ +void bm_engine_search_word_translation_extended(Engine* engine, gchar* word) +{ + g_debug("%s->%s() called.\n",__FILE__,__FUNCTION__); +} +//------------------------------------------------------------------------------ +void bm_engine_set_progress_seed(Engine* engine, gchar* signal, gdouble seed) { + g_debug("%s->%s() called.\n",__FILE__,__FUNCTION__); + XDXFData* data = (XDXFData*)(engine->engine_data); + if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) { + data->cb_progress_caching_seed = seed; + g_debug("%s->%s() sets new seed=%0.2f for for signal " + "\"%s\".\n", + __FILE__, + __FUNCTION__, + seed, + signal + ); + } + else { + g_warning("%s->%s() unsupported signal" + "for progress: %s.\n", + __FILE__, + __FUNCTION__, + signal + ); + }; +} +//------------------------------------------------------------------------------ +gpointer bm_engine_set_callbacks(Engine* engine, + gchar* signal, + gpointer c_handler, + gpointer user_data) +{ + g_debug("%s->%s() called.\n",__FILE__,__FUNCTION__); + g_assert(engine != NULL); + g_assert(signal != NULL); + g_assert(c_handler != NULL); + XDXFData* data = (XDXFData*)(engine->engine_data); + if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) { + gpointer result = data->cb_progress_caching; + data->cb_progress_caching = c_handler; + data->cb_progress_caching_data = user_data; + g_debug("%s->%s() sets handler for signal \"%s\".\n", + __FILE__, + __FUNCTION__, + signal + ); + g_debug("%s->%s() Function at adress = %d.\n", + __FILE__, + __FUNCTION__, + (guint)c_handler + ); + g_debug("%s->%s() Data at adress = %d.\n", + __FILE__, + __FUNCTION__, + (guint)user_data + ); + return result; + } + else if(g_ascii_strcasecmp(signal, ENGINE_WORD_LIST_SIGNAL) == 0) { + gpointer result = data->cb_search_word_list; + data->cb_search_word_list = c_handler; + data->cb_search_word_list_data = user_data; + g_debug("%s->%s() sets handler for signal \"%s\".\n", + __FILE__, + __FUNCTION__, + signal + ); + g_debug("%s->%s() Function at adress = %d.\n", + __FILE__, + __FUNCTION__, + (guint)c_handler + ); + g_debug("%s->%s() Data at adress = %d.\n", + __FILE__, + __FUNCTION__, + (guint)user_data + ); + return result; + } + else if(g_ascii_strcasecmp(signal, + ENGINE_WORD_TRANSLATION_SIGNAL) == 0) { + gpointer result = data->cb_search_word_trans; + data->cb_search_word_trans = c_handler; + data->cb_search_word_trans_data = user_data; + g_debug("%s->%s() sets handler for signal \"%s\".\n", + __FILE__, + __FUNCTION__, + signal + ); + g_debug("%s->%s() Function at adress = %d.\n", + __FILE__, + __FUNCTION__, + (guint)c_handler + ); + g_debug("%s->%s() Data at adress = %d.\n", + __FILE__, + __FUNCTION__, + (guint)user_data + ); + return result; + } + else { + g_warning("%s->%s() unsupported signal: %s.\n", + __FILE__, + __FUNCTION__, + signal + ); + return NULL; + } +} +//------------------------------------------------------------------------------ +void bm_engine_close(Engine* engine) +{ + g_debug("%s->%s() called.\n-->PARAM: engine adress=%p\n", + __FILE__, + __FUNCTION__, + engine); + if(engine == NULL) { + g_warning("%s->%s() Trying delete not existed engine.\n", + __FILE__, + __FUNCTION__ + ); + return; + } + XDXFData* data = (XDXFData*)(engine->engine_data); + if(data->cache != NULL) { + gnome_vfs_close(data->cache); + }; + if(data->xdxf != NULL) { + gnome_vfs_close(data->xdxf); + }; + + g_free(data->dict_path); + g_free(data); + g_free(engine); + g_debug("%s->%s() engine at adress=%p is deleted.\n", + __FILE__, + __FUNCTION__, + engine); +} +//------------------------------------------------------------------------------ +gchar* bm_engine_error_message(EngineStatus error) +{ + g_debug("%s->%s() called.\n",__FILE__,__FUNCTION__); + return "Error - not yet implemented."; +} +//------------------------------------------------------------------------------ +Engine* bm_engine_create(gchar* location, + EngineOptimizationFlag auto_cache, + cb_progress progress_handler, + gpointer progress_data, + gdouble seed) +{ + g_debug("%s->%s() called.\n" + "-->PARAM:location=\'%s\'\n" + "-->PARAM:auto_cache=%d\n", + __FILE__, + __FUNCTION__, + location, + (guint)auto_cache + ); + timer(TIMER_START,(gchar*)__FUNCTION__); + GnomeVFSResult open_result; + + if(!gnome_vfs_initialized ()) { + gnome_vfs_init (); + }; + + gchar* tmp = g_strdup(location); + string_to_path(&tmp); + + Engine* result = (Engine*)g_try_malloc(sizeof(Engine)); + result->engine_location = bm_engine_location; + result->engine_is_optimized = bm_engine_is_optimized; + result->engine_optimize = bm_engine_optimize; + result->engine_search_word_list = bm_engine_search_word_list; + result->engine_search_word_translation = + bm_engine_search_word_translation; + + result->engine_close = bm_engine_close; + result->engine_status = bm_engine_error; + result->engine_error_message = bm_engine_error_message; + result->engine_set_callback = bm_engine_set_callbacks; + result->engine_set_progress_seed = bm_engine_set_progress_seed; + result->engine_set_auto_free = bm_engine_set_auto_free; + // API 0.2 + result->engine_add_word = bm_engine_add_word; + result->engine_remove_word = bm_engine_remove_word; + + XDXFData* data = (XDXFData*)g_try_malloc(sizeof(XDXFData)); + result->engine_data = (gpointer)data; + + + g_debug("%s->%s() opening file...\'%s\'.\n", + __FILE__, + __FUNCTION__, + location + ); + gchar* tmp2 = g_strconcat(tmp,"/ws_bookmarks.xdxf",NULL); + open_result = + gnome_vfs_open (&(data->xdxf), tmp2, GNOME_VFS_OPEN_READ | + GNOME_VFS_OPEN_WRITE | GNOME_VFS_OPEN_RANDOM); + g_free(tmp2); tmp2 = NULL; + + if(open_result != GNOME_VFS_OK) { + g_warning("%s->%s() opening dictionary file failed" + " due to reason: %s.\n", + __FILE__, + __FUNCTION__, + gnome_vfs_result_to_string(open_result) + ); + result->engine_data = NULL; + g_free(data); + g_free(result); + result = NULL; + } + else { + g_debug("%s->%s() opening dictionary file successed.\n", + __FILE__, + __FUNCTION__ + ); + data->dict_path = g_strdup(tmp); + data->cache = NULL; + data->cb_progress_caching = progress_handler; + data->cb_progress_caching_data = progress_data; + data->cb_progress_caching_seed = seed; + data->cb_progress_word_list = NULL; + data->cb_progress_word_list_data = NULL; + data->cb_progress_word_list_seed = 0.01; + data->cb_progress_word_trans = NULL; + data->cb_progress_word_trans_data = NULL; + data->cb_progress_word_trans_seed = 0.01; + + data->cb_search_word_list = NULL; + data->cb_search_word_list_data = NULL; + + data->cb_search_word_trans = NULL; + data->cb_search_word_trans_data = NULL; + + data->auto_free = FALSE; + if(auto_cache != ENGINE_NO) { + if(auto_cache == ENGINE_REFRESH) { + bm_engine_optimize(result); + } + else if(auto_cache == ENGINE_CREATE) { + gchar* cache_path = g_strconcat(data->dict_path, + "/ws_bookmarks.cache", + NULL); + open_result = + gnome_vfs_open (&(data->cache), + cache_path, + GNOME_VFS_OPEN_READ + ); + if(open_result != GNOME_VFS_OK) { + bm_engine_optimize(result); + }; + g_free(cache_path); cache_path = NULL; + } + }; + } + g_free(tmp); tmp = NULL; + + timer(TIMER_STOP,(gchar*)__FUNCTION__); + g_debug("%s->%s() returned Engine at adress=%p\n TO NAPEWNO TEN PLIK", + __FILE__, + __FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +EngineModule engine_global_functions() +{ + g_debug("%s->%s() called.\n",__FILE__,__FUNCTION__); + EngineModule* result = g_try_new(EngineModule, 1); + result->engine_check = bm_engine_check; + result->engine_description = bm_engine_description; + result->engine_format = bm_engine_format; + result->engine_version = bm_engine_version; + result->engine_create = bm_engine_create; + g_debug("%s->%s() returned EngineModule at adress=%p.\n", + __FILE__, + __FUNCTION__, + result + ); + return *result; +} +//------------------------------------------------------------------------------ +static double timer(gboolean start, gchar* message) +{ + static GArray* stack = NULL; + static gboolean first_run = TRUE; + static struct timeval actual_time; + static struct timeval last_time; + static struct timeval result; + static double seconds = 0.0; + if(first_run) { + first_run = FALSE; + stack = g_array_new(TRUE, TRUE, sizeof(struct timeval)); + }; + + if (start) { + g_debug("XDXF->%s() start counting time for function '%s()'.\n", + __FUNCTION__, + message + ); + g_array_prepend_val(stack, actual_time); + gettimeofday(&g_array_index(stack, struct timeval, 0),NULL); + return -1.0; + } + // we just want to end some timer - print some information about + // working time; + else { + gettimeofday(&actual_time,NULL); + last_time = g_array_index(stack, struct timeval, 0); + g_array_remove_index(stack, 0); + + if (actual_time.tv_usec < last_time.tv_usec) { + int nsec = (last_time.tv_usec - actual_time.tv_usec) / + (1000000 + 1); + last_time.tv_usec -= 1000000 * nsec; + last_time.tv_sec += nsec; + } + if (actual_time.tv_usec - last_time.tv_usec > 1000000) { + int nsec = (last_time.tv_usec - actual_time.tv_usec) / + 1000000; + last_time.tv_usec += 1000000 * nsec; + last_time.tv_sec -= nsec; + } + result.tv_sec = actual_time.tv_sec - last_time.tv_sec; + result.tv_usec = actual_time.tv_usec - last_time.tv_usec; + seconds = (((double)(result.tv_usec)) / 1e6) + + ((double)(result.tv_sec)); + + g_debug("XDXF->%s() function \'%s()\' was working for: %g [s] " + "or %ld [us].\n", + __FUNCTION__, + message, + seconds, + ((long)(result.tv_sec*1e6)+(result.tv_usec)) + ); + // stack is empty so we delete everything + if(stack->len == 0) + { + g_array_free(stack, TRUE); + first_run = TRUE; + } + } + return seconds; +} +//------------------------------------------------------------------------------ +static gchar* read_file_part(FilePart* part, GnomeVFSHandle* file) +{ + g_debug("%s->%s() called.\n",__FILE__,__FUNCTION__); + timer(TIMER_START,(gchar*)__FUNCTION__); + gchar* result = NULL; + GnomeVFSResult f_result; + GnomeVFSFileSize bytes_read; + + f_result = gnome_vfs_seek(file, GNOME_VFS_SEEK_START, part->offset); + if(f_result != GNOME_VFS_OK) { + g_warning("%s->%s() failed. Not possible to seek " + "through file!\n", + __FILE__, + __FUNCTION__ + ); + timer(TIMER_STOP,(gchar*)__FUNCTION__); + return result; + + }; + result = g_try_malloc((part->length + 1) * sizeof(gchar)); + if(result == NULL) { + g_warning("%s->%s() failed. Not possible to allocate " + "so big memmory chunk!\n", + __FILE__, + __FUNCTION__ + ); + timer(TIMER_STOP,(gchar*)__FUNCTION__); + return result; + }; + f_result = gnome_vfs_read (file, result, part->length, &bytes_read); + if((f_result != GNOME_VFS_OK) || + (((gulong)bytes_read) != part->length)) { + g_debug("%s->%s() failed. Not possible to read from " + "file!\n", + __FILE__, + __FUNCTION__ + ); + timer(TIMER_STOP,(gchar*)__FUNCTION__); + g_free(result); result = NULL; + return result; + }; + result[part->length] = '\0'; + + g_debug("%s->%s() returned string=\n\'%s\'.\n", + __FILE__, + __FUNCTION__, + result + ); + timer(TIMER_STOP,(gchar*)__FUNCTION__); + return result; +} +//------------------------------------------------------------------------------ +/** Translate given string to proper full file path. Function works "in-situ". +* It means that string is translated and replaced by proper full file path if +* this file path exists, or this string is cleared and setted to NULL, if string +* was representing wrong path. This function is static - to use only +* within this module. +* +* @param string :: gchar** - pointer to pointer to string +* representing file path - it will be replaced by a proper filepath. +* It should be path to directory or file, ended with "/" or not, absolute +* or not +* @return gchar* - pointer to new full file path, it is the same +* as string[0] in fact and it is returned only for abillity of nesting of +* functions by pointer to string identyfying full file path +*/ +static gchar* string_to_path(gchar** string) { + g_debug("%s->%s() called.\n\ + -->PARAM:string=\'%s\'\n", + __FILE__, + __FUNCTION__, + string[0] + ); + gchar* arg = string[0]; + gchar* new = NULL; + // cleaning from leading and trailing whitespaces + g_strstrip(arg); + // add current directory if this is not absolute directory + if (!g_path_is_absolute(arg)) { + gchar* tmp = g_get_current_dir(); + new = g_strconcat(tmp,"/",arg,NULL); + g_free(arg); arg = new; new = NULL; + }; + // this is not a directory + if (!g_file_test(arg, G_FILE_TEST_IS_DIR)) { + // if this is wrong filepath, string was wrong + if (!g_file_test(arg, G_FILE_TEST_IS_REGULAR)) { + g_free(arg); + new = NULL; + } + //if this is a file, remove filename + else + { + new = g_path_get_dirname (arg); + g_free(arg); + } + } + // this is a directory + else { + // remove suffix "/" if neded... + if (g_str_has_suffix(arg,"/") ) { + new = g_path_get_dirname (arg); + g_free(arg); + } + else { + new = arg; + } + }; + // now in new should be proper filepath, if not, string was wrong + if (!g_file_test(new, G_FILE_TEST_IS_DIR)) { + // if that directory does not exist, passed string wasn't proper + g_free(new); + new = NULL; + }; + // replace string under passed address + string[0] = new; + g_debug("%s->%s() returned string=\'%s\'\n", + __FILE__, + __FUNCTION__, + string[0] + ); + return new; +} +//------------------------------------------------------------------------------ +static gboolean is_bm_file(gchar* file) { + g_debug("%s->%s() called.\n\ + -->PARAM:file=\'%s\'\n", + __FILE__, + __FUNCTION__, + file + ); + gboolean result = TRUE; + GnomeVFSHandle* fd = NULL; + GnomeVFSResult file_result; + GnomeVFSFileSize bytes_read; + + if(!gnome_vfs_initialized ()) { + gnome_vfs_init (); + }; + + file_result = gnome_vfs_open (&fd, file, GNOME_VFS_OPEN_READ); + if(file_result != GNOME_VFS_OK) { + g_warning("%s->%s() Could not open the file.\n", + __FILE__, + __FUNCTION__ + ); + return FALSE; + }; + + XML_Parser p = XML_ParserCreate(NULL); + if (!p) { + g_warning("%s->%s() Could not open initialize " + "XML parser.\n", + __FILE__, + __FUNCTION__ + ); + gnome_vfs_close(fd); + return FALSE; + }; + XML_SetElementHandler(p, is_bm_file_start, is_bm_file_end); + XDXFCheckingData user_data = {TRUE, FALSE, 0}; + XML_SetUserData(p, &user_data); + gchar buffer[DICT_CACHEING_BUFF_SIZE]; + + guint loop_count = 0; + while(TRUE) { + file_result = gnome_vfs_read (fd, + buffer, + DICT_CACHEING_BUFF_SIZE, + &bytes_read + ); + if (file_result != GNOME_VFS_OK) { + result = FALSE; + g_warning("%s->%s() Could not read enought from" + " file.\n", + __FILE__, + __FUNCTION__ + ); + break; + }; + if (! XML_Parse(p, + buffer, + (gulong)bytes_read, + ((gulong)bytes_read) < DICT_CACHEING_BUFF_SIZE + ) ) { + result = FALSE; + g_warning("%s->%s() Could not parse file.\n", + __FILE__, + __FUNCTION__ + ); + break; + }; + if (user_data.further == FALSE) { + result = user_data.good; + g_debug("%s->%s() statement: location is " + "compatible with this module, is %s\n", + __FILE__, + __FUNCTION__, + PRINT_STATE(result) + ); + break; + }; + if (loop_count > 1) { + result = FALSE; + g_debug("%s->%s() Wrong file format.\n", + __FILE__, + __FUNCTION__ + ); + break; + }; + loop_count++; + } + + gnome_vfs_close(fd); + XML_ParserFree(p); + g_debug("%s->%s() returned bool statement=%s.\n", + __FILE__, + __FUNCTION__, + PRINT_STATE(result) + ); + return result; +} +//------------------------------------------------------------------------------ +static void is_bm_file_start(void *data, const char *el, const char **attr) +{ + XDXFCheckingData* user_data = (XDXFCheckingData*)data; + if (user_data->deep == 0) { + if (g_utf8_collate (el,"xdxf") != 0) { + user_data->good = FALSE; + } + else { + user_data->good = TRUE; + } + user_data->further = FALSE; + } + user_data->deep++; +} +//------------------------------------------------------------------------------ +static void is_bm_file_end(void *data, const char *el) +{ + // clear as far as in this callback is nothing to do +} +//------------------------------------------------------------------------------ +EngineStatus bm_engine_error(Engine* engine) +{ + g_debug("%s->%s() called.\n",__FILE__,__FUNCTION__); + XDXFData* data = (XDXFData*)(engine->engine_data); + g_debug("%s->%s() returned error code: %d\n", + __FILE__, + __FUNCTION__, + (gint)(data->last_error) + ); + return data->last_error; +} +//------------------------------------------------------------------------------ +static void caching_expat_start(void *data, const char *el, const char **attr) { + XDXFCacheData* loc_data = (XDXFCacheData*)data; + if(g_utf8_collate(el,"ar") == 0) { + loc_data->last_start = + XML_GetCurrentByteIndex(loc_data->parser); + } + else if(g_utf8_collate(el,"k") == 0) { + loc_data->state = 1; + } + else { + loc_data->state = 0; + } +} +//------------------------------------------------------------------------------ +static void caching_expat_end(void *data, const char *el) { + XDXFCacheData* loc_data = (XDXFCacheData*)data; + loc_data->last_stop = XML_GetCurrentByteIndex(loc_data->parser); + + static guint record_length; + static guint start; + static guint length; + static guint buffer_length; + + if((g_utf8_collate("k",el) == 0) && + (loc_data->state == 1)) { + loc_data->state = 2; + } + else if((g_utf8_collate("ar",el) == 0) && + (loc_data->state == 2)) { + buffer_length = loc_data->buffer_length; + record_length = sizeof(guint)*3 + loc_data->buffer_length; + start = loc_data->last_start; + length = loc_data->last_stop + strlen("") - + loc_data->last_start; + + gboolean error_writting = FALSE; + GnomeVFSFileSize bytes_written; + GnomeVFSResult vfs_result; + vfs_result = gnome_vfs_write(loc_data->cache, + &record_length, + sizeof(guint), + &bytes_written + ); + if(vfs_result != GNOME_VFS_OK) error_writting = TRUE; + vfs_result = gnome_vfs_write(loc_data->cache, + loc_data->buffer, + loc_data->buffer_length, + &bytes_written + ); + if(vfs_result != GNOME_VFS_OK) error_writting = TRUE; + vfs_result = gnome_vfs_write(loc_data->cache, + &start, + sizeof(guint), + &bytes_written + ); + if(vfs_result != GNOME_VFS_OK) error_writting = TRUE; + vfs_result = gnome_vfs_write(loc_data->cache, + &length, + sizeof(guint), + &bytes_written + ); + if(vfs_result != GNOME_VFS_OK) error_writting = TRUE; + + loc_data->buffer[0] = '\0'; + loc_data->buffer_length = 0; + loc_data->state = 0; + }; +} +//------------------------------------------------------------------------------ +static void caching_expat_text(void *data, const XML_Char *txt, int len) { + XDXFCacheData* loc_data = (XDXFCacheData*)data; + + if(loc_data->state == 1) { + memcpy(&(loc_data->buffer[loc_data->buffer_length]), + (gchar*)txt, + len + ); + loc_data->buffer_length += (long)len; + loc_data->buffer[loc_data->buffer_length] = '\0'; + }; +} +//------------------------------------------------------------------------------ +static guint64 get_file_size(GnomeVFSHandle* file) +{ + guint64 result = 0; + guint64 old_pos = 0; + gnome_vfs_tell(file, &old_pos); + + if( gnome_vfs_seek(file, GNOME_VFS_SEEK_END, 0) != GNOME_VFS_OK) { + return 0; + } + + if( gnome_vfs_tell(file, &result) != GNOME_VFS_OK) { + result = 0; + } + + gnome_vfs_seek(file, GNOME_VFS_SEEK_START, old_pos); + return result; +} +//------------------------------------------------------------------------------ +/* +static gboolean is_Bookmark_file(gchar* file) { + LOGS("Bookmark/%s->%s() called.\n\ + -->PARAM:file=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + file + ); + + GnomeVFSHandle *handle; + + GnomeVFSResult result = gnome_vfs_open (&handle, file, GNOME_VFS_OPEN_READ); + + if(result != GNOME_VFS_OK) { + LOGS("File Access Error.\n"); + return FALSE; + } + + if( g_strrstr (file, "ws_bookmarks") == NULL) { + LOGS("Wrong file! Not a bookmarks' database.\n"); + return FALSE; + } + return TRUE; +}*/ + +void bm_engine_optimize(Engine* engine) +{ + g_debug("%s->%s() called for engine at adress=%p\n", + __FILE__, + __FUNCTION__, + engine + ); + timer(TIMER_START,(gchar*)__FUNCTION__); + GnomeVFSResult vfs_result; + XDXFData* data = (XDXFData*)(engine->engine_data); + g_debug("data->dict_path %s", data->dict_path); + gchar* cache_path = g_strconcat(data->dict_path,"/ws_bookmarks.cache",NULL); + vfs_result = gnome_vfs_create(&(data->cache), + cache_path, + GNOME_VFS_OPEN_WRITE, + FALSE, + 0666 + ); + if(vfs_result != GNOME_VFS_OK) { + data->cache = NULL; + g_warning("%s->%s().Could not create new cache file: %s.\n", + __FILE__, + __FUNCTION__, + cache_path + ); + } + else { + XDXFCacheData* c_data = + (XDXFCacheData*)g_try_malloc(sizeof(XDXFCacheData)); + c_data->parser = XML_ParserCreate(NULL); + c_data->cache = data->cache; + c_data->buffer = + (gchar*)g_try_malloc(sizeof(gchar)*DICT_CACHEING_BUFF_SIZE); + c_data->buffer_length = 0; + c_data->last_start = 0; + c_data->last_stop = 0; + c_data->last_length = 0; + guint64 file_size = get_file_size(data->xdxf); +// g_debug("%s->%s(): caching dictionaries size is %.2f kB " +// "[%d bytes = %.2f MB].\n", +// __FILE__, +// __FUNCTION__, +// ((gdouble)file_size)/1024.0, +// file_size, +// ((gdouble)file_size)/(1024.0*1024.0) +// ); + + XML_SetUserData(c_data->parser, (gpointer)c_data); + XML_SetElementHandler(c_data->parser, + caching_expat_start, + caching_expat_end + ); + XML_SetCharacterDataHandler(c_data->parser, caching_expat_text); + GnomeVFSFileSize bytes_readed = DICT_CACHEING_BUFF_SIZE; + gchar b[DICT_CACHEING_BUFF_SIZE + 1]; + gdouble last_prog = 0; + while(TRUE) { + vfs_result = gnome_vfs_read(data->xdxf, + b, + DICT_CACHEING_BUFF_SIZE, + &bytes_readed + ); + XML_Parse(c_data->parser, + b, + bytes_readed, + bytes_readed < DICT_CACHEING_BUFF_SIZE + ); + if(data->cb_progress_caching != NULL) { + GnomeVFSFileSize act_pos; + gnome_vfs_tell(data->xdxf, &act_pos); + gdouble progress = ((gdouble)act_pos)/ + ((gdouble)file_size); + if((( (progress - last_prog) / + (data->cb_progress_caching_seed) ) > 1.0) || + (progress >= 1.0)) { + data->cb_progress_caching( + progress, + data->cb_progress_caching_data, + ENGINE_NO_ERROR + ); + last_prog = progress; + }; + } + if(bytes_readed < DICT_CACHEING_BUFF_SIZE) break; + } + g_free(c_data->buffer); + g_free(c_data); + } + + vfs_result = gnome_vfs_close(data->cache); + vfs_result = gnome_vfs_open(&(data->cache), + cache_path, + GNOME_VFS_OPEN_READ + ); + g_free(cache_path); cache_path = NULL; + timer(TIMER_STOP,(gchar*)__FUNCTION__); + g_debug("%s->%s()'s work finished.\n",__FILE__,__FUNCTION__); +} +//------------------------------------------------------------------------------ +gboolean bm_engine_check(gchar* location) +{ + g_debug("%s->%s() called.\n-->PARAM:location=\'%s\'\n", + __FILE__, + __FUNCTION__, + location + ); + timer(TIMER_START,(gchar*)__FUNCTION__); + gboolean result = TRUE; + gchar* filepath = g_strdup(location); + gchar* tmp = NULL; + + string_to_path(&filepath); + if (filepath == NULL) { + result = FALSE; + g_warning("%s->%s() location \'%s\' is not a proper " + "path!\n", + __FILE__, + __FUNCTION__, + location + ); + } + else { + tmp = g_strconcat(filepath,"/ws_bookmarks.xdxf",NULL); + g_free(filepath); + filepath = tmp; + tmp = NULL; + + g_debug("%s->%s() finnal file to check is: %s\n", + __FILE__, + __FUNCTION__, + filepath + ); + if (!g_file_test(filepath, G_FILE_TEST_IS_REGULAR)) { + g_warning("%s->%s() file \'%s\' does not " + "exists!\n", + __FILE__, + __FUNCTION__, + filepath + ); + result = FALSE; + }; + }; + if (result != FALSE) { + result = is_bm_file(filepath); + }; + + g_free(filepath); + timer(TIMER_STOP,(gchar*)__FUNCTION__); + g_debug("%s->%s() returned bool statement=%s.\n", + __FILE__, + __FUNCTION__, + PRINT_STATE(result) + ); + return result; +} + + +//------------------------------------------------------------------------------ +static guint get_max_length(gchar* a, guint length) +{ + gchar* b = a; + guint len = 0; + guint n = 0; + memcpy(&n,b,sizeof(guint)); + while((len + n) <= (length - 4)) { + len += n; + b = b + n; + memcpy(&n,b,sizeof(guint)); + } + return len; +} +//------------------------------------------------------------------------------ // finished functions: +void bm_engine_set_auto_free(Engine* engine, gboolean state) +{ + g_debug("%s->%s() called.\n" + "-->PARAM:engine at adress=%p\n" + "-->PARAM:state=%s\n", + __FILE__, + __FUNCTION__, + engine, + PRINT_STATE(state) + ); + g_assert(engine != NULL); + XDXFData* data = (XDXFData*)(engine->engine_data); + data->auto_free = state; + g_debug("%s->%s() Current auto_free is %s\n", + __FILE__, + __FUNCTION__, + PRINT_STATE(data->auto_free) + ); +} +//------------------------------------------------------------------------------ +gchar* bm_engine_version() +{ + g_debug("%s->%s() called.\n",__FILE__,__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_VERSION); + g_debug("%s->%s() return string=%s\n", + __FILE__, + __FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_format() +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_FORMAT); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_description() +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_DESCRIPTION); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +gboolean bm_engine_is_optimized(Engine* engine) +{ + g_debug("%s->%s() called.\n-->PARAM: engine adress=%p\n", + __FILE__, + __FUNCTION__, + engine + ); + g_assert(engine != NULL); + XDXFData* data = (XDXFData*)(engine->engine_data); + gboolean result = (data->cache != NULL); + g_debug("%s->%s() returned bool statement=%s.\n", + __FILE__, + __FUNCTION__, + PRINT_STATE(result) + ); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_location(Engine* engine) +{ + g_debug("%s->%s() called.\n-->PARAM: engine adress=%p\n", + __FILE__, + __FUNCTION__, + engine + ); + g_assert(engine != NULL); + XDXFData* data = (XDXFData*)(engine->engine_data); + gchar* result; + if(data->auto_free) { + result = data->dict_path; + } + else { + result = g_strdup(data->dict_path); + } + + g_debug("%s->%s() returned string=%s\n", + __FILE__, + __FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +static void search_word_list_start(void *data, + const char *el, + const char **attr + ) +{ + XDXFWordsListData* loc_data = (XDXFWordsListData*)data; + if(g_utf8_collate(el,"k") == 0) { + loc_data->one_word = 1; + }; +} +//------------------------------------------------------------------------------ +static void search_word_list_end(void *data, const char *el) +{ + XDXFWordsListData* loc_data = (XDXFWordsListData*)data; + if(g_utf8_collate(el,"k") == 0) { + loc_data->one_word = 0; + } + else { + return; + } + static gboolean any_found = FALSE; + gboolean matched = FALSE; + + if(( loc_data->last_word_length >= loc_data->pattern_len ) && + (g_ascii_strncasecmp(loc_data->last_word, + loc_data->pattern, + loc_data->pattern_len) == 0)) { + matched = TRUE; + any_found = TRUE; + gchar* new = g_strdup(loc_data->last_word); + g_array_append_val((loc_data->result), new); + g_debug("New Word for pattern \"%s\" found: %s\n", + loc_data->pattern, + new + ); + }; + // "clearing" buffer for next word + loc_data->last_word_length = 0; + // if we passed words matching -> ends + if(any_found && !matched) { + loc_data->cont = FALSE; + }; + matched = FALSE; + any_found = FALSE; +} +//------------------------------------------------------------------------------ +static void search_word_list_text(void *data, const XML_Char *txt, int len) +{ + XDXFWordsListData* loc_data = (XDXFWordsListData*)data; + + if(loc_data->one_word == 1) { + memcpy(&(loc_data->last_word[loc_data->last_word_length]), + (gchar*)txt, + len + ); + loc_data->last_word_length += (guint)len; + loc_data->last_word[loc_data->last_word_length] = '\0'; + }; +} +//------------------------------------------------------------------------------ +// return translation of word using cache file +static void word_list_cache(XDXFData* data, gchar* pattern, GArray* result) { + gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 0); +// GnomeVFSResult vfs_result; + GnomeVFSFileSize bytes_readed; + guint64 file_size = get_file_size(data->cache); + if (file_size > 0){ + guint pattern_len; + gchar buffer[DICT_SEARCHING_WORD_LIST_BUFF_SIZE]; + gchar* buf; + guint record_length = 0; + guint already = 0; + guint max_length = 0; + pattern_len = g_strlen(pattern); + g_strstrip(pattern); + if ((int)(pattern[0]) == 42 && pattern[1] == '\0') //asterix? + { + gchar pattern_copy[2] = "A\0"; + + pattern_len = g_strlen(pattern_copy); + while (TRUE) + { + + record_length = 0; + already = 0; + max_length = 0; + //gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 0); + // + while(TRUE) { + gnome_vfs_read(data->cache, + buffer, + DICT_SEARCHING_WORD_LIST_BUFF_SIZE, + &bytes_readed + ); + + max_length = get_max_length(buffer, (guint)bytes_readed); + already += max_length; + buf = buffer; + + guint how_far = 0; + while(how_far < max_length) { + memcpy(&record_length, buf, sizeof(guint)); + if( + ((record_length - 3*sizeof(guint)) >= pattern_len) && + (g_ascii_strncasecmp(buf + sizeof(guint), + pattern_copy, + pattern_len + ) == 0 ) ) { + gchar* new = + g_strndup(buf + sizeof(guint), + record_length - + 3*sizeof(guint)); + g_array_append_val(result, new); + g_debug( + "New Word for pattern \"%s\" found: " + "%s\n", + pattern_copy, + new + ); + }; + how_far += record_length; + buf = buf + record_length; + } + if((bytes_readed < DICT_SEARCHING_WORD_LIST_BUFF_SIZE)|| + (already > (file_size -3))) { + break; + } + gnome_vfs_seek(data->cache, + GNOME_VFS_SEEK_CURRENT, + ((gint)max_length) - + DICT_SEARCHING_WORD_LIST_BUFF_SIZE + ); + } + pattern_copy[0] = (gchar)((gint) pattern_copy[0] + 1); + + g_debug("now this is pattern %d ", (gint) pattern_copy[0]); + if ((gint) pattern_copy[0] > 90) break; + gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 0); + } + }else + { + while(TRUE) { + gnome_vfs_read(data->cache, + buffer, + DICT_SEARCHING_WORD_LIST_BUFF_SIZE, + &bytes_readed + ); + + max_length = get_max_length(buffer, (guint)bytes_readed); + already += max_length; + buf = buffer; + + guint how_far = 0; + while(how_far < max_length) { + memcpy(&record_length, buf, sizeof(guint)); + if( + ((record_length - 3*sizeof(guint)) >= pattern_len) && + (g_ascii_strncasecmp(buf + sizeof(guint), + pattern, + pattern_len + ) == 0 ) ) { + gchar* new = + g_strndup(buf + sizeof(guint), + record_length - + 3*sizeof(guint)); + g_array_append_val(result, new); + g_debug( + "New Word for pattern \"%s\" found: " + "%s\n", + pattern, + new + ); + }; + how_far += record_length; + buf = buf + record_length; + } + if((bytes_readed < DICT_SEARCHING_WORD_LIST_BUFF_SIZE)|| + (already > (file_size -3)) ) { + + break; + } + gnome_vfs_seek(data->cache, + GNOME_VFS_SEEK_CURRENT, + ((gint)max_length) - + DICT_SEARCHING_WORD_LIST_BUFF_SIZE + ); + } + } + } + timer(TIMER_STOP,(gchar*)__FUNCTION__); + timer(TIMER_START,"callback for returning words list START"); + data->cb_search_word_list(result, + pattern, + data->cb_search_word_list_data, + ENGINE_NO_ERROR + ); + timer(TIMER_STOP,"callback for returning words list END"); +} +//------------------------------------------------------------------------------ +// return translation of word but using only xdxf dictionary file +static void word_list_xdxf(XDXFData* data, gchar* pattern, GArray* result) { + gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, 0); + GnomeVFSResult vfs_result; + GnomeVFSFileSize bytes_readed = DICT_SEARCHING_WORD_LIST_BUFF_SIZE; + gchar buffer[DICT_SEARCHING_WORD_LIST_BUFF_SIZE+1]; + guint64 file_size = get_file_size(data->xdxf); + guint pattern_len; + + XML_Parser parser = XML_ParserCreate(NULL); + if (!parser) { + g_warning("%s->%s() Could not open initialize XML " + "parser.\n", + __FILE__, + __FUNCTION__ + ); + timer(TIMER_STOP,(gchar*)__FUNCTION__); + return; + }; + + + gchar tmp[DICT_MAX_WORD_LENGTH]; + XML_SetElementHandler(parser, + search_word_list_start, + search_word_list_end + ); + XML_SetCharacterDataHandler(parser, search_word_list_text); + + // buffer for single word + // pattern to search + // length of pattern + // actal length of readed word + // array to append words + // continuation of the same word + // continue of searching? + XDXFWordsListData search_data = {tmp, + pattern, + pattern_len, + 0, + result, + 0, + TRUE + }; + XML_SetUserData(parser, &search_data); + + gdouble last_prog = 0; + + while(TRUE) { + vfs_result = gnome_vfs_read(data->xdxf, + buffer, + DICT_SEARCHING_WORD_LIST_BUFF_SIZE, + &bytes_readed + ); + XML_Parse(parser, + buffer, + bytes_readed, + bytes_readed < DICT_SEARCHING_WORD_LIST_BUFF_SIZE + ); + + if(data->cb_progress_word_list != NULL) { + GnomeVFSFileSize act_pos; + gnome_vfs_tell(data->xdxf, &act_pos); + gdouble progress = ((gdouble)act_pos)/ + ((gdouble)file_size); + if((((progress - last_prog)/ + (data->cb_progress_word_list_seed)) > 1.0) || + (progress >= 1.0)) { + data->cb_progress_word_list( + progress, + data->cb_progress_word_list_data, + ENGINE_NO_ERROR + ); + last_prog = progress; + }; + } + if(bytes_readed < DICT_SEARCHING_WORD_LIST_BUFF_SIZE) { + break; + } + if((search_data.cont) == FALSE) { + g_debug("%s->%s() We found every words matching " + "pattern \"%s\". Abort further searching.\n", + __FILE__, + __FUNCTION__, + pattern + ); + break; + } + } + + + + + XML_ParserFree(parser); + + timer(TIMER_STOP,(gchar*)__FUNCTION__); + timer(TIMER_START,"callback for returning words list START"); + data->cb_search_word_list(result, + pattern, + data->cb_search_word_list_data, + ENGINE_NO_ERROR + ); + timer(TIMER_STOP,"callback for returning words list END"); +} +//------------------------------------------------------------------------------ +void bm_engine_search_word_list(Engine* engine, gchar* pattern) +{ + g_debug("%s->%s() called. Searching words list\n" + "-->PARAM:engine at adress=%p\n" + "-->PARAM:pattern=\"%s\"\n", + __FILE__, + __FUNCTION__, + engine, + pattern + ); + g_assert(engine != NULL); + g_assert(pattern != NULL); + + timer(TIMER_START,(gchar*)__FUNCTION__); + XDXFData* data = (XDXFData*)(engine->engine_data); + if(data->cb_search_word_list == NULL) { + g_warning("%s->%s() callback for Word List not set. " + "Searching aborted.\n", + __FILE__, + __FUNCTION__ + ); + timer(TIMER_STOP,(gchar*)__FUNCTION__); + return; + }; + + + GArray* result = g_array_new(TRUE,FALSE,sizeof(gchar*)); + // dictionary is optimized so search in cache file + if(data->cache != NULL) { + word_list_cache(data, pattern, result); + } + // dictionary is not optimized so search directly fom XDXF file + else { + word_list_xdxf(data, pattern, result); + }; + + if(data->auto_free == TRUE) { + g_debug("%s->%s() deleting all dynamic data because " + "AUTO_FREE=TRUE\n", + __FILE__, + __FUNCTION__ + ); + gchar* tmp; + guint i = 0; + while((tmp = g_array_index(result, gchar*, i)) != NULL) + { + g_free(tmp); tmp = NULL; + i++; + } + g_array_free(result, TRUE); + }; + g_debug("%s->%s() finished definately its work.\n", + __FILE__, + __FUNCTION__ + ); + return; +} diff --git a/src/bookmarks/xdxf/src/engine_bookmark_old.c b/src/bookmarks/xdxf/src/engine_bookmark_old.c new file mode 100644 index 0000000..44e21dc --- /dev/null +++ b/src/bookmarks/xdxf/src/engine_bookmark_old.c @@ -0,0 +1,975 @@ +/****************************************************************************** +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +******************************************************************************/ + +// header with data structure and function definition for XDXF engine. +// Also Engine API. +#include +//------------------------------------------------------------------------------ + +#ifndef NOLOGS +#include +#include +#include +#endif + +#define LOGS g_debug + +/*inline void LOGS(gchar* frm, ...) { +#ifndef NOLOGS + //g_printf(frm); +#endif +}*/ + +//============================================================================== +//============================================================================== +//============================================================================== +//-------------------------------------- FUNCTION FROM API 0.2 !!! +//============================================================================== +int get_id(void* data,int n,char** argv,char** names) { + int len = strlen(&(argv[0][0])); + memcpy(data,&(argv[0][0]), len); + gchar* tmp = (gchar*)data; + tmp[len] = 0; + return 0; +} + +gboolean bm_engine_add_word(Engine* engine, + gchar* word, + gchar* translation) { + + LOGS("Bookmark/%s->%s() called. Param\nEngine at address: %p\n" + "word: %s\ntranslation address: %p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine, + word, + translation + ); + g_assert(engine != NULL); + g_assert(word != NULL); + g_assert(translation != NULL); + + // start timer for this function + timer(TIMER_START, (gchar*)(gchar*)__FUNCTION__); + + BookData* data = (BookData*)(engine->engine_data); + + timer(TIMER_STOP, (gchar*)(gchar*)__FUNCTION__); + return result; +} +//------------------------------------------------------------------------------ +gboolean bm_engine_remove_word(Engine* engine, gchar* word) { + gint sql_res = 0; + gchar* err = NULL; + gboolean result = TRUE; + + LOGS("Bookmark/%s->%s() called. Param\nEngine at address: %p\n" + "word: %s\n",(gchar*)__FILE__,(gchar*)__FUNCTION__,engine,word); + g_assert(engine != NULL); + g_assert(word != NULL); + timer(TIMER_START, (gchar*)(gchar*)__FUNCTION__); + + BookData* data = (BookData*)(engine->engine_data); +/* + gchar* tmp = g_utf8_strdown(word,-1); + gchar* sql = g_strconcat("DELETE FROM translations WHERE word_id = " + "(SELECT id FROM words WHERE word=\'", + tmp, + "\');", + NULL + ); + g_free(tmp); tmp = NULL; + sql_res = sqlite_exec(data->db, sql, NULL, NULL, &err); + if(err || sql_res!=0) { + LOGS("Error while deleting \'%s\' word translation(s):\n%s\n",word,err); + g_free(sql); sql = NULL; + return FALSE; + } + g_free(sql); sql = NULL; + + gchar* sql = g_strconcat("DELETE FROM translations WHERE word LIKE \'", + word, + "\';", + NULL + ); +*/ + gchar* sql = sqlite_mprintf("DELETE FROM translations WHERE word LIKE " + "\'%q\';", word); + sql_res = sqlite_exec(data->db, sql, NULL, NULL, &err); + if(err || sql_res!=0) { + LOGS("Error while deleting \'%s\' <-> reason:\n%s\n",word,err); + g_free(sql); sql = NULL; + return FALSE; + } + g_free(sql); sql = NULL; + + timer(TIMER_STOP, (gchar*)(gchar*)__FUNCTION__); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_get_lang_from(Engine* engine) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup("any"); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_get_lang_to(Engine* engine) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup("any"); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_get_title(Engine* engine) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strconcat(g_get_user_name(),"s' bookmarks",NULL); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +gchar* bm_engine_get_icon_path(Engine* engine) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup("/usr/share/pixmaps/ws_eng_bookmark_icon.png"); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} + +//============================================================================== +//============================================================================== +//============================================================================== +//-------------------------------------- FUNCTION TO WRITE (NOT IMPLEMENTED YET) +//============================================================================== + +//------------------------------------------------------------------------------ +// searching word by concrete engine +void bm_engine_search_word_translation(Engine* engine, gchar* word) +{ + g_debug("XDXF/%s->%s() called.\n" + "-->PARAM:engine at adress=%p\n" + "-->PARAM:word=\'%s\'\n", + __FILE__, + __FUNCTION__, + engine, + word); + g_assert(engine != NULL); + g_assert(word != NULL); + // start timer for this function + timer(TIMER_START, (gchar*)__FUNCTION__); + XDXFData* data = (XDXFData*)(engine->engine_data); + // if callback is not set, we do not have to search word + if(data->cb_search_word_trans == NULL) { + g_warning("XDXF/%s->%s() callback for Word Translation not set." + " Searching aborted.\n", + __FILE__, + __FUNCTION__ + ); + timer(TIMER_STOP,(gchar*)__FUNCTION__); + // do not send any signal, just exit + return; + }; + + guint word_length = strlen(word); + gchar* trans; + + // dictionary is optimized + if(data->cache != NULL) { + trans = word_translation_cache(data, word); + // dictionary is not optimized right now + } else + { + trans = word_translation_xdxf(data, word); + }; + + g_debug("XDXF/%s->%s() found for word \'%s\' translation:\n\'%s\'\n", + __FILE__, + __FUNCTION__, + word, + trans + ); + timer(TIMER_STOP,(gchar*)__FUNCTION__); + timer(TIMER_START,"callback for returning word's translation START"); + // calling callback for word translation + data->cb_search_word_trans(trans, + word, + data->cb_search_word_trans_data, + ENGINE_NO_ERROR + ); + timer(TIMER_STOP,"callback for returning word's translation END"); + if(data->auto_free) { + g_debug("XDXF/%s->%s() deleting all dynamic data because " + "AUTO_FREE=TRUE\n", + __FILE__, + __FUNCTION__ + ); + g_free(trans); + } + trans = NULL; + return; +} + +//------------------------------------------------------------------------------ +void bm_engine_close(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM: engine adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine); + g_assert(engine != NULL); + + BookData* data = (BookData*)(engine->engine_data); + sqlite_close(data->db); + + LOGS("Bookmark/%s->%s() engine at adress=%p is deleted.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine); + g_free(engine); + engine = NULL; +} +//------------------------------------------------------------------------------ + +Engine* bm_engine_create(gchar* location, + EngineOptimizationFlag auto_cache, + cb_progress progress_handler, + gpointer progress_data, + gdouble seed) +{ + LOGS("Bookmark/%s->%s() called.\n" + "-->PARAM:location=\'%s\'\n" + "-->PARAM:auto_cache=%d\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + location, + (guint)auto_cache + ); + timer(TIMER_START,(gchar*)(gchar*)__FUNCTION__); + + gchar* tmp = g_strdup(location); + string_to_path(&tmp); + + Engine* result = (Engine*)g_try_malloc(sizeof(Engine)); + result->engine_location = bm_engine_location; + result->engine_is_optimized = bm_engine_is_optimized; + result->engine_optimize = bm_engine_optimize; + result->engine_search_word_list = bm_engine_search_word_list; + result->engine_search_word_translation = + bm_engine_search_word_translation; + result->engine_close = bm_engine_close; + result->engine_status = bm_engine_status; + result->engine_error_message = bm_engine_status_message; + result->engine_set_callback = bm_engine_set_callback; + result->engine_set_progress_seed = bm_engine_set_progress_seed; + result->engine_set_auto_free = bm_engine_set_auto_free; + // 0.2 API: + result->engine_add_word = bm_engine_add_word; + result->engine_remove_word = bm_engine_remove_word; + result->engine_get_lang_from = bm_engine_get_lang_from; + result->engine_get_lang_to = bm_engine_get_lang_to; + result->engine_get_title = bm_engine_get_title; + result->engine_get_icon_path = bm_engine_get_icon_path; + + + BookData* data = (BookData*)g_try_malloc(sizeof(BookData)); + result->engine_data = (gpointer)data; + + LOGS("Bookmark/%s->%s() opening file...\'%s\'.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + location + ); + gchar* tmp2 = g_strconcat(tmp,"/ws_bookmarks",NULL); + gchar* err; + data->db = sqlite_open(tmp2,0600,&err); + g_free(tmp2); tmp2 = NULL; + if(!(data->db)) { + LOGS("Bookmark/%s->%s() opening bookmark file failed.%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + err + ); + g_free(err); + g_free(data); + g_free(result); + result = NULL; + } + else { + LOGS("Bookmark/%s->%s()opening dictionary file successed.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + data->dict_path = g_strdup(tmp); + data->cb_progress_caching = progress_handler; + data->cb_progress_caching_data = progress_data; + data->cb_progress_caching_seed = seed; + data->cb_progress_word_list = NULL; + data->cb_progress_word_list_data = NULL; + data->cb_progress_word_list_seed = 0.01; + data->cb_progress_word_trans = NULL; + data->cb_progress_word_trans_data = NULL; + data->cb_progress_word_trans_seed = 0.01; + + data->cb_search_word_list = NULL; + data->cb_search_word_list_data = NULL; + + data->cb_search_word_trans = NULL; + data->cb_search_word_trans_data = NULL; + + data->auto_free = FALSE; + // there is no cache mechanizm in bookmarks + } + g_free(tmp); tmp = NULL; + + timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + LOGS("Bookmark/%s->%s() returned Engine at adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ + + + +static gboolean is_Bookmark_file(gchar* file) { + LOGS("Bookmark/%s->%s() called.\n\ + -->PARAM:file=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + file + ); + gchar* err; + sqlite* tmp = sqlite_open(file,0600,&err); + if(err || tmp==NULL) { + LOGS("Wrong file! Not a sqlite database.\n"); + g_free(err); + return FALSE; + } + + gint result = 0; + gchar sql[] = "SELECT COUNT(word) FROM translations WHERE word=\'.\';"; + + result = sqlite_exec(tmp, sql, NULL, NULL, &err); + if(err || result!=0) { + LOGS("Wrong database! Not a bookmark.\n"); + g_free(err); + sqlite_close(tmp); + return FALSE; + } + sqlite_close(tmp); + return TRUE; +} +//------------------------------------------------------------------------------ + + +void bm_engine_optimize(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called for engine at adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine + ); + LOGS("Unsupported optimization mechanizm for this engine!\n"); + LOGS("Bookmark/%s->%s()'s work finished.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); +} +//------------------------------------------------------------------------------ +gboolean bm_engine_check(gchar* location) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM:location=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + location + ); + timer(TIMER_START,(gchar*)(gchar*)__FUNCTION__); + gboolean result = TRUE; + gchar* filepath = g_strdup(location); + gchar* tmp = NULL; + + string_to_path(&filepath); + if (filepath == NULL) { + result = FALSE; + LOGS("Bookmark/%s->%s() location \'%s\' is not a proper " + "path!\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + location + ); + } + else { + tmp = g_strconcat(filepath,"/ws_bookmarks",NULL); + g_free(filepath); + filepath = tmp; + tmp = NULL; + + LOGS("Bookmark/%s->%s() finnal file to check is: %s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + filepath + ); + if (!g_file_test(filepath, G_FILE_TEST_IS_REGULAR)) { + LOGS("Bookmark/%s->%s() file \'%s\' does not exists!\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + filepath + ); + result = FALSE; + }; + }; + if (result != FALSE) { + result = is_Bookmark_file(filepath); + }; + + g_free(filepath); + timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + LOGS("Bookmark/%s->%s() returned bool statement=%s.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + PRINT_STATE(result) + ); + return result; +} + +//------------------------------------------------------------------------------ +gboolean bm_engine_is_optimized(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM: engine adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine + ); + g_assert(engine != NULL); + gboolean result = FALSE; + LOGS("Bookmark/%s->%s() returned bool statement=%s.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + PRINT_STATE(result) + ); + return result; +} +//------------------------------------------------------------------------------ + +void bm_engine_search_word_list(Engine* engine, gchar* pattern) +{ + LOGS("Bookmark/%s->%s() called. Searching words list\n" + "-->PARAM:engine at adress=%p\n" + "-->PARAM:pattern=\"%s\"\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine, + pattern + ); + g_assert(engine != NULL); + g_assert(pattern != NULL); + + timer(TIMER_START,(gchar*)(gchar*)__FUNCTION__); + BookData* data = (BookData*)(engine->engine_data); + if(data->cb_search_word_list == NULL) { + LOGS("Bookmark/%s->%s() callback for Word List not set. " + "Searching aborted.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + return; + }; + + + gchar* tmp = g_utf8_strdown(pattern,-1); + sqlite_vm* query = NULL; + gchar* sql = NULL; + gchar* tran = NULL; + + + sql = g_strconcat("SELECT word FROM translations WHERE " + "word LIKE \'",tmp,"\%\';",NULL); + LOGS("QUERY: %s\n",sql); + gint sql_res = 0; + const gchar* end; + gchar* err = NULL; + sql_res = sqlite_compile(data->db, /* The open database */ + (const gchar*)sql, /* SQL statement to be compiled */ + &end, /* OUT: uncompiled tail of zSql */ + &query, /* OUT: the virtual machine */ + &err /* OUT: Error message. */ + ); + if(err || sql_res!=0) { + LOGS("Error while compiling query:\n%s\nreason:%s\n",sql,err); + g_free(sql); sql = NULL; + return; + }; + gint nCol = 0; + const gchar** values = NULL; + const gchar** head = NULL; + gint status = 0; + gboolean first = TRUE; + GArray* result = g_array_new(TRUE, TRUE, sizeof(gchar*) ); + do { + first = TRUE; + do { + if(!first) sleep(1); + first = FALSE;; + status = sqlite_step( + query, + &nCol, + &values, + &head + ); + if(status == SQLITE_ERROR) { + LOGS("Error while making next step\n"); + g_free(sql); sql = NULL; + return; + }; + if(status == SQLITE_ROW) { + LOGS("Fount new word: \"%s\"\n",&(values[0][0])); + gchar* tmp = g_strdup((gchar*)&(values[0][0])); + g_array_append_val(result, tmp ); + } + } while((status == SQLITE_BUSY) && (status != SQLITE_ERROR)); + } while((status == SQLITE_ROW) && (status != SQLITE_ERROR)); + sqlite_finalize(query,&err); + timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__); + + + timer(TIMER_START,"callback for returning words LIST START"); + // calling callback for word translation + + data->cb_search_word_list(result , pattern, data->cb_search_word_list_data, ENGINE_NO_ERROR); + + timer(TIMER_STOP,"callback for returning word LIST END"); + if(data->auto_free) { + LOGS("Bookmark/%s->%s() deleting all dynamic data because " + "AUTO_FREE=TRUE\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__ + ); + g_free(tran); + } +} + +//============================================================================== +//============================================================================== +//============================================================================== +//---------------------------------------------------------- COMPLETED FUNCTIONS +//============================================================================== +// global functions +EngineModule engine_global_functions() +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + EngineModule* result = g_try_new(EngineModule, 1); + result->engine_check = bm_engine_check; + result->engine_description = bm_engine_description; + result->engine_format = bm_engine_format; + result->engine_version = bm_engine_version; + result->engine_create = bm_engine_create; + LOGS("Bookmark/%s->%s()returned EngineModule at adress=%p.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return *result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_status_message(error) +gchar* bm_engine_status_message(EngineStatus error) +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + switch (error) { + case ENGINE_NO_ERROR: + return "No error."; + case ENGINE_WRONG_FILE: + return "File which You are trying to use is wrong type."; + case ENGINE_COULDNT_READ: + return "Could not read from file."; + case ENGINE_NO_FILE: + return "There is no such a file."; + case ENGINE_OUT_OF_MEMORY: + return "There were no enough memory for this action."; + default: + return "Wrong engine's status identifier!"; + } +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_module_get_version(module) +gchar* bm_engine_version() +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_VERSION); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_module_get_format(module) +gchar* bm_engine_format() +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_FORMAT); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_module_get_description(module) +gchar* bm_engine_description() +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_DESCRIPTION); + LOGS("Bookmark/%s->%s() return string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_get_location(engine) +gchar* bm_engine_location(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called.\n-->PARAM: engine adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine + ); + g_assert(engine != NULL); + BookData* data = (BookData*)(engine->engine_data); + + gchar* result; + if(data->auto_free) { + result = data->dict_path; + } + else { + result = g_strdup(data->dict_path); + } + + LOGS("Bookmark/%s->%s() returned string=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_set_auto_free(engine, state) +void bm_engine_set_auto_free(Engine* engine, gboolean state) +{ + LOGS("Bookmark/%s->%s() called.\n" + "-->PARAM:engine at adress=%p\n" + "-->PARAM:state=%s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine, + PRINT_STATE(state) + ); + g_assert(engine != NULL); + BookData* data = (BookData*)(engine->engine_data); + + data->auto_free = state; + LOGS("Bookmark/%s->%s() Current auto_free is %s\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + PRINT_STATE(data->auto_free) + ); +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_get_last_status(engine) +EngineStatus bm_engine_status(Engine* engine) +{ + LOGS("Bookmark/%s->%s() called.\n" + "-->PARAM:engine at adress=%p\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + engine + ); + BookData* data = (BookData*)(engine->engine_data); + LOGS("Bookmark/%s->%s() returned error code: %d\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (gint)(data->last_error) + ); + return data->last_error; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_set_progress_seed(engine, signal, val) +void bm_engine_set_progress_seed(Engine* engine, gchar* signal, gdouble seed) { + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + BookData* data = (BookData*)(engine->engine_data); + if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) { + data->cb_progress_caching_seed = seed; + LOGS("Bookmark/%s->%s() sets new seed=%0.2f for for signal " + "\"%s\".\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + seed, + signal + ); + } + else { + LOGS("Bookmark/%s->%s() unsupported signalfor progress: %s.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + }; +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_set_callback(engine,signal,c_handler,data) +gpointer bm_engine_set_callback(Engine* engine, + gchar* signal, + gpointer c_handler, + gpointer user_data) +{ + LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__); + g_assert(engine != NULL); + g_assert(signal != NULL); + g_assert(c_handler != NULL); + BookData* data = (BookData*)(engine->engine_data); + if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) { + gpointer result = data->cb_progress_caching; + data->cb_progress_caching = c_handler; + data->cb_progress_caching_data = user_data; + LOGS("Bookmark/%s->%s() sets handler for signal \"%s\".\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + LOGS("Bookmark/%s->%s() Function at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)c_handler + ); + LOGS("Bookmark/%s->%s() Data at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)user_data + ); + return result; + } + else if(g_ascii_strcasecmp(signal, ENGINE_WORD_LIST_SIGNAL) == 0) { + gpointer result = data->cb_search_word_list; + data->cb_search_word_list = c_handler; + data->cb_search_word_list_data = user_data; + LOGS("Bookmark/%s->%s() sets handler for signal \"%s\".\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + LOGS("Bookmark/%s->%s() Function at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)c_handler + ); + LOGS("Bookmark/%s->%s() Data at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)user_data + ); + return result; + } + else if(g_ascii_strcasecmp(signal, + ENGINE_WORD_TRANSLATION_SIGNAL) == 0) { + gpointer result = data->cb_search_word_trans; + data->cb_search_word_trans = c_handler; + data->cb_search_word_trans_data = user_data; + LOGS("Bookmark/%s->%s() sets handler for signal \"%s\".\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + LOGS("Bookmark/%s->%s() Function at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)c_handler + ); + LOGS("Bookmark/%s->%s() Data at adress = %d.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + (guint)user_data + ); + return result; + } + else { + g_warning("Bookmark/%s->%s() unsupported signal: %s.\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + signal + ); + return NULL; + } +} + + + + + + +//============================================================================== +//============================================================================== +//============================================================================== +//---------------------------------------------------------- HELPFULLY FUNCTIONS +//============================================================================== + +//------------------------------------------------------------------------------ +static gchar* string_to_path(gchar** string) { + LOGS("Bookmark/%s->%s() called.\n\ + -->PARAM:string=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + string[0] + ); + gchar* arg = string[0]; + gchar* new = NULL; + // cleaning from leading and trailing whitespaces + g_strstrip(arg); + // add current directory if this is not absolute directory + if (!g_path_is_absolute(arg)) { + gchar* tmp = g_get_current_dir(); + new = g_strconcat(tmp,"/",arg,NULL); + g_free(arg); arg = new; new = NULL; + }; + // this is not a directory + if (!g_file_test(arg, G_FILE_TEST_IS_DIR)) { + // if this is wrong filepath, string was wrong + if (!g_file_test(arg, G_FILE_TEST_IS_REGULAR)) { + g_free(arg); + new = NULL; + } + //if this is a file, remove filename + else + { + new = g_path_get_dirname (arg); + g_free(arg); + } + } + // this is a directory + else { + // remove suffix "/" if neded... + if (g_str_has_suffix(arg,"/") ) { + new = g_path_get_dirname (arg); + g_free(arg); + } + else { + new = arg; + } + }; + // now in new should be proper filepath, if not, string was wrong + if (!g_file_test(new, G_FILE_TEST_IS_DIR)) { + // if that directory does not exist, passed string wasn't proper + g_free(new); + new = NULL; + }; + // replace string under passed address + string[0] = new; + LOGS("Bookmark/%s->%s() returned string=\'%s\'\n", + (gchar*)__FILE__, + (gchar*)__FUNCTION__, + string[0] + ); + return new; +} +//------------------------------------------------------------------------------ +static double timer(gboolean start, gchar* message) +{ + static GArray* stack = NULL; + static gboolean first_run = TRUE; + static struct timeval actual_time; + static struct timeval last_time; + static struct timeval result; + static double seconds = 0.0; + if(first_run) { + first_run = FALSE; + stack = g_array_new(TRUE, TRUE, sizeof(struct timeval)); + }; + + if (start) { + LOGS("Bookmark->%s() start timer for function '%s()'.\n", + (gchar*)__FUNCTION__, + message + ); + g_array_prepend_val(stack, actual_time); + gettimeofday(&g_array_index(stack, struct timeval, 0),NULL); + return -1.0; + } + // we just want to end some timer - print some information about + // working time; + else { + gettimeofday(&actual_time,NULL); + last_time = g_array_index(stack, struct timeval, 0); + g_array_remove_index(stack, 0); + + if (actual_time.tv_usec < last_time.tv_usec) { + int nsec = (last_time.tv_usec - actual_time.tv_usec) / + (1000000 + 1); + last_time.tv_usec -= 1000000 * nsec; + last_time.tv_sec += nsec; + } + if (actual_time.tv_usec - last_time.tv_usec > 1000000) { + int nsec = (last_time.tv_usec - actual_time.tv_usec) / + 1000000; + last_time.tv_usec += 1000000 * nsec; + last_time.tv_sec -= nsec; + } + result.tv_sec = actual_time.tv_sec - last_time.tv_sec; + result.tv_usec = actual_time.tv_usec - last_time.tv_usec; + seconds = (((double)(result.tv_usec)) / 1e6) + + ((double)(result.tv_sec)); + + LOGS("Bookmark->%s() function \'%s()\' was working for: %g " + "[s] or %ld [us].\n", + (gchar*)__FUNCTION__, + message, + seconds, + ((long)(result.tv_sec*1e6)+(result.tv_usec)) + ); + // stack is empty so we delete everything + if(stack->len == 0) + { + g_array_free(stack, TRUE); + first_run = TRUE; + } + } + return seconds; +} +//------------------------------------------------------------------------------ + + + diff --git a/src/bookmarks/xdxf/src/test.c b/src/bookmarks/xdxf/src/test.c new file mode 100644 index 0000000..b1b4abe --- /dev/null +++ b/src/bookmarks/xdxf/src/test.c @@ -0,0 +1,144 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#include +#include +#include +#include + + +getting_additional get_functions; // additinal functions for concrete module (e.g. XDXF) + +void print_list(GArray* list, gchar* pattern, gpointer user_data, EngineStatus error) { + printf((gchar*)user_data,pattern); + int i = 0; + while(g_array_index(list, gchar*, i) != NULL) + { + printf(" %d. : %s\n",i+1,g_array_index(list, gchar*, i)); + i++; + } + printf("--------------------------------------------------\n"); +} + +void print_translation(gchar* translation, gchar* word, gpointer user_data, EngineStatus error) { + printf((gchar*)user_data,word); + printf("%s\n\nTRANSLATION ENDS.\n",translation); +} + +void caching_progress(gdouble value, gpointer user_data, EngineStatus error) { + printf((gchar*)user_data,value); +} + +int main(int argc, char** argv) +{ + char* nameApp = "StarDictEngine test: "; + printf("%sStarting test program of module: dictionary_engine.\n",nameApp); + + + gchar* current_directory = g_get_current_dir(); + printf("%sCurrent directory: %s\n",nameApp,current_directory); + gchar* library_to_path = g_strconcat(current_directory, "/ws_bookmark.so", NULL); + printf("%sEngine library should be in location:\n\t%s\n",nameApp,library_to_path); + + GModule *library = g_module_open(library_to_path, G_MODULE_BIND_LAZY); + if(!library) { + printf("%sLoading module failed. \nReason: %s\n",nameApp,g_module_error()); + return 1; + }; + + //dict_eng_module_get_global_functions(library,get_functions); + g_module_symbol ( (library),_GLOBAL_FUNCTIONS_NAME_, (gpointer)&get_functions); + if(get_functions == NULL) { + printf("%sLoading function failed\n",nameApp); + return 2; + } + else printf("%sLoading function OK\n",nameApp); + + EngineModule module = get_functions(); + printf("Module description: %s\n",dict_eng_module_get_description(module)); + Engine* sd; + + gboolean is_compatible = dict_eng_module_check(module,"ws_bookmarks"); + if(is_compatible == TRUE) + { + printf("Location is compatible with enigne!\n"); + } + else { + printf("Location is not compatible with enigne!\n"); + return 1; + } + + //printf("%sCheck OK. Module description: %s\n", nameApp, dict_eng_module_get_description(module)); + + //xdxf = dict_eng_module_create_ext(module, "/home/lukasz/MyDocs/repo/WhiteStork/trunk/engine/bin" , ENGINE_CREATE, caching_progress, "Current progress of caching is: %0.2f.\n", 0.03 ); + //home/stranger/whitestork/engine0.2/ +// xdxf = dict_eng_module_create(module, "/home/stranger/whitestork/engine0.2/" , ENGINE_NO); +// dict_eng_set_callback(xdxf, ENGINE_PROGRESS_CACHING, caching_progress, "Current progress of caching is: %0.2f.\n"); +// dict_eng_set_progress_seed(xdxf, ENGINE_PROGRESS_CACHING, 0.02); + +/* if(dict_eng_is_optimized(xdxf) == FALSE) + { + printf("Dictionary has no cache!\nCreating cache file....\n"); + dict_eng_optimize(xdxf); + } + else { + printf("Dictionary has already cache file!\n"); + }*/ + sd = dict_eng_module_create(module, + "ws_bookmarks" , + ENGINE_CREATE); + printf("Lokacja: %s\n",dict_eng_get_location(sd)); + + dict_eng_set_callback(sd, + ENGINE_WORD_LIST_SIGNAL, + print_list, + "Word list matches to pattern: %s\n" + ); + dict_eng_set_callback(sd, + ENGINE_WORD_TRANSLATION_SIGNAL , + print_translation, + "Translation for word\'%s\':\n"); + + dict_eng_search_word_list(sd,"12"); + //dict_eng_search_word_translation(sd,"1 word"); + +// dict_eng_remove_word(sd, "stranger"); +// dict_eng_remove_word(sd, "gandzia"); +// dict_eng_remove_word(sd, "lukas"); + dict_eng_add_word(sd, "stranger", "autor pluginu tego wlasnie to jest!"); + dict_eng_add_word(sd, "gandzia", "rulez"); + dict_eng_add_word(sd, "lukas", "pawlik"); +// dict_eng_remove_word(sd, "stranger"); + + dict_eng_search_word_translation(sd,"stranger"); + + dict_eng_add_word(sd, "stranger", "autor pluginu tego wlasnie to jest!"); + dict_eng_search_word_translation(sd,"stranger"); + dict_eng_search_word_list(sd,"gandzia"); + + printf("Lang FROM:%s\n",dict_eng_get_lang_from(sd)); + printf(" Lang TO:%s\n",dict_eng_get_lang_to(sd)); + printf(" Title:%s\n",dict_eng_get_title(sd)); + printf("Icon path:%s\n",dict_eng_get_icon_path(sd)); + + dict_eng_destroy(sd); + printf("%sClosed.\n",nameApp); + return 0; +} + diff --git a/src/bookmarks/xdxf/src/test1.c b/src/bookmarks/xdxf/src/test1.c new file mode 100644 index 0000000..b89a9a7 --- /dev/null +++ b/src/bookmarks/xdxf/src/test1.c @@ -0,0 +1,144 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#include +#include +#include +#include + + +getting_additional get_functions; // additinal functions for concrete module (e.g. XDXF) + +void print_list(GArray* list, gchar* pattern, gpointer user_data, EngineStatus error) { + printf((gchar*)user_data,pattern); + int i = 0; + while(g_array_index(list, gchar*, i) != NULL) + { + printf(" %d. : %s\n",i+1,g_array_index(list, gchar*, i)); + i++; + } + printf("--------------------------------------------------\n"); +} + +void print_translation(gchar* translation, gchar* word, gpointer user_data, EngineStatus error) { + printf((gchar*)user_data,word); + printf("%s\n\nTRANSLATION ENDS.\n",translation); +} + +void caching_progress(gdouble value, gpointer user_data, EngineStatus error) { + printf((gchar*)user_data,value); +} + +int main(int argc, char** argv) +{ + char* nameApp = "StarDictEngine test: "; + printf("%sStarting test program of module: dictionary_engine.\n",nameApp); + + + gchar* current_directory = g_get_current_dir(); + printf("%sCurrent directory: %s\n",nameApp,current_directory); + gchar* library_to_path = g_strconcat(current_directory, "/ws_bookmark.so", NULL); + printf("%sEngine library should be in location:\n\t%s\n",nameApp,library_to_path); + + GModule *library = g_module_open(library_to_path, G_MODULE_BIND_LAZY); + if(!library) { + printf("%sLoading module failed. \nReason: %s\n",nameApp,g_module_error()); + return 1; + }; + + //dict_eng_module_get_global_functions(library,get_functions); + g_module_symbol ( (library),_GLOBAL_FUNCTIONS_NAME_, (gpointer)&get_functions); + if(get_functions == NULL) { + printf("%sLoading function failed\n",nameApp); + return 2; + } + else printf("%sLoading function OK\n",nameApp); + + EngineModule module = get_functions(); + printf("Module description: %s\n",dict_eng_module_get_description(module)); + Engine* sd; + + gboolean is_compatible = dict_eng_module_check(module,"/home/str/whitestork/engines/bookmark/ws_bookmarks"); + if(is_compatible == TRUE) + { + printf("Location is compatible with enigne!\n"); + } + else { + printf("Location is not compatible with enigne!\n"); + return 1; + } + + //printf("%sCheck OK. Module description: %s\n", nameApp, dict_eng_module_get_description(module)); + + //xdxf = dict_eng_module_create_ext(module, "/home/lukasz/MyDocs/repo/WhiteStork/trunk/engine/bin" , ENGINE_CREATE, caching_progress, "Current progress of caching is: %0.2f.\n", 0.03 ); + //home/stranger/whitestork/engine0.2/ +// xdxf = dict_eng_module_create(module, "/home/stranger/whitestork/engine0.2/" , ENGINE_NO); +// dict_eng_set_callback(xdxf, ENGINE_PROGRESS_CACHING, caching_progress, "Current progress of caching is: %0.2f.\n"); +// dict_eng_set_progress_seed(xdxf, ENGINE_PROGRESS_CACHING, 0.02); + +/* if(dict_eng_is_optimized(xdxf) == FALSE) + { + printf("Dictionary has no cache!\nCreating cache file....\n"); + dict_eng_optimize(xdxf); + } + else { + printf("Dictionary has already cache file!\n"); + }*/ + sd = dict_eng_module_create(module, + "/home/str/whitestork/engines/bookmark/ws_bookmarks" , + ENGINE_CREATE); + printf("Lokacja: %s\n",dict_eng_get_location(sd)); + + dict_eng_set_callback(sd, + ENGINE_WORD_LIST_SIGNAL, + print_list, + "Word list matches to pattern: %s\n" + ); + dict_eng_set_callback(sd, + ENGINE_WORD_TRANSLATION_SIGNAL , + print_translation, + "Translation for word\'%s\':\n"); + + dict_eng_search_word_list(sd,"12"); + //dict_eng_search_word_translation(sd,"1 word"); + + dict_eng_remove_word(sd, "stranger"); + dict_eng_remove_word(sd, "gandzia"); + dict_eng_remove_word(sd, "lukas"); + dict_eng_add_word(sd, "stranger", "autor pluginu tego wlasnie to jest!"); + dict_eng_add_word(sd, "gandzia", "rulez"); + dict_eng_add_word(sd, "lukas", "pawlik"); + dict_eng_remove_word(sd, "stranger"); + + dict_eng_search_word_translation(sd,"stranger"); + + dict_eng_add_word(sd, "stranger", "autor pluginu tego wlasnie to jest!"); + dict_eng_search_word_translation(sd,"stranger"); + dict_eng_search_word_list(sd,"gandzia"); + + printf("Lang FROM:%s\n",dict_eng_get_lang_from(sd)); + printf(" Lang TO:%s\n",dict_eng_get_lang_to(sd)); + printf(" Title:%s\n",dict_eng_get_title(sd)); + printf("Icon path:%s\n",dict_eng_get_icon_path(sd)); + + dict_eng_destroy(sd); + printf("%sClosed.\n",nameApp); + return 0; +} + diff --git a/src/bookmarks/xdxf/src/test2.c b/src/bookmarks/xdxf/src/test2.c new file mode 100644 index 0000000..6179a5a --- /dev/null +++ b/src/bookmarks/xdxf/src/test2.c @@ -0,0 +1,28 @@ +#include + +int main (void) +{ + + if(!gnome_vfs_initialized ()) { + gnome_vfs_init (); + }; + + gchar *buffer = "test"; + GnomeVFSHandle *handle; + GnomeVFSResult result; + GnomeVFSFileSize ile; + + result = gnome_vfs_open (&handle, "/home/krzsas/WhiteStork/trunk/src/bookmarks/src/ws_bookmarks", GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_WRITE | GNOME_VFS_OPEN_RANDOM); + if (result == GNOME_VFS_OK) + { + gnome_vfs_seek (handle, GNOME_VFS_SEEK_END, 0); + gnome_vfs_write (handle, buffer, strlen(buffer), &ile); + + g_printf ("Zapisano: %d\n", ile); +// gnome_vfs_close(handle); + } + + else g_printf ("Blad %d: %s\n", result, gnome_vfs_result_to_string (result)); + + return 0; +}; diff --git a/src/bookmarks/xdxf/src/testMakeDatabase.c b/src/bookmarks/xdxf/src/testMakeDatabase.c new file mode 100644 index 0000000..7ca65e1 --- /dev/null +++ b/src/bookmarks/xdxf/src/testMakeDatabase.c @@ -0,0 +1,135 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ + +#include +#include +#include + +const guint records_number = 1000; + +// ---------------------------------------------------------------------------------- +sqlite* database_make(gchar* path) { + gchar* buffer = NULL; + sqlite* result = NULL; + // creatingh database + result = sqlite_open(path, + 0600, + &buffer); + // check if everything was okey + if(!result) { + g_printf("Error while trying to create database:\n%s\n",buffer); + g_free(buffer); buffer = NULL; + return NULL; + }; + // return pointer to database + return result; +} +// ---------------------------------------------------------------------------------- +gint database_add_test_table(sqlite* db) { + gint result = 0; + //gchar sql[] = "CREATE TABLE words(id INTEGER PRIMARY KEY, word TEXT UNIQUE);"; + gchar sql2[] = "CREATE TABLE translations(id INTEGER PRIMARY KEY, word TEXT, translation TEXT);"; + gchar* err = NULL; +/* + result = sqlite_exec(db, sql, NULL, NULL, &err); + if(err || result!=0) { + g_printf("Error while creating \'words\' table:\n%s\n",err); + return 1; + } +*/ + result = sqlite_exec(db, sql2, NULL, NULL, &err); + if(err || result!=0) { + g_printf("Error while creating \'translations\' table:\n%s\n",err); + return 2; + } + + return result; +} +// ---------------------------------------------------------------------------------- +gint database_add_test_record(sqlite* db, guint i) { + gint result = 0; + gchar* sql = NULL; + gchar* err = NULL; + gint last_id = 0; + gint word_count = 1; + gchar buffer[] = " "; + gchar last_char[] = " "; + gchar tran[] = "this is a translation number 10.000 for word 10.000 word <-----"; + g_sprintf(buffer,"%d word",i); +/* + sql = g_strconcat("INSERT INTO words VALUES(NULL,\'",buffer,"\');", NULL); + result = sqlite_exec(db, sql, NULL, NULL, &err); + if(err || result!=0) { + g_printf("Error while trying to add new word %d:\n%s\n",i,err); + g_free(sql); + return 1; + } + g_free(sql); + last_id = sqlite_last_insert_rowid(db); + g_sprintf(last_char,"%d",last_id); +*/ + if(i == 5000) { + word_count = 5; + g_printf("Adding more records for word - test\n"); + } + gint j; + for(j=0; j + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/src/dbus_wrapper/Doxyfile b/src/dbus_wrapper/Doxyfile new file mode 100644 index 0000000..27787aa --- /dev/null +++ b/src/dbus_wrapper/Doxyfile @@ -0,0 +1,1237 @@ +# Doxyfile 1.4.6 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = White Stork DBus Wrapper Module + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 0.1 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc/ + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ../../include/ws_dbus.h + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = No + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 1 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO \ No newline at end of file diff --git a/src/dbus_wrapper/Makefile b/src/dbus_wrapper/Makefile new file mode 100644 index 0000000..ffc74ad --- /dev/null +++ b/src/dbus_wrapper/Makefile @@ -0,0 +1,21 @@ +CC=gcc +LIBS=`pkg-config --libs glib-2.0 libosso` +CFLAGS=`pkg-config --cflags glib-2.0 libosso` +DEBUG = -g -Wall +BINARY = bin +MAIN_BINARY = ../../bin +INCLUDE = ../../include +SOURCE = src +DOCS = doc + +all: ${BINARY}/ws_dbus.o + @cp ${BINARY}/* ${MAIN_BINARY} + +docs: + doxygen Doxyfile + +${BINARY}/ws_dbus.o: + @${CC} ${DEBUG} -c ${SOURCE}/ws_dbus.c -o ${BINARY}/ws_dbus.o ${CFLAGS} -I${INCLUDE} +clean: + -rm -rf ${BINARY}/* + -rm -rf ${DOCS}/* diff --git a/src/dbus_wrapper/src/ws_dbus.c b/src/dbus_wrapper/src/ws_dbus.c new file mode 100644 index 0000000..d9be50f --- /dev/null +++ b/src/dbus_wrapper/src/ws_dbus.c @@ -0,0 +1,891 @@ +/* +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Copyright 2006 ComArch S.A. +*/ + +#include + + +struct _WSDBusMethodData +{ + GQuark id; + gchar *name; + gpointer handler; + gpointer user_data; + gchar* data_types; +}; + + +typedef struct _WSDBusMethodData WSDBusMethodData; + +/*static WSDBusStatus ws_dbus_send_method_data (WSDBusData *ws_dbus_data);*/ +static gchar* ws_dbus_get_ptr2method (GArray *methods, gchar* name ); +static void ws_dbus_libosso_errors (osso_return_t result); +static void ws_dbus_fill_message (DBusMessage *msg, void *data); + +static gchar* ws_dbus_get_ptr2method (GArray *methods, gchar* name) + +{ + guint i; + gchar* temp; + + g_debug ("%d", methods->len); + + return NULL; + + for (i = 0; i < methods->len; i+=2) + + { + temp = g_array_index (methods, gchar *,i); + + if (strcmp (name, temp) == 0) { + temp = g_array_index (methods, gchar *,i+1); + g_debug ("\nData types: %s\n", temp); + return temp; + } + + }; + + return NULL; +}; + +static void ws_dbus_libosso_errors (osso_return_t result) + +{ + switch (result) + { + case OSSO_OK: + g_debug ("All OK\n"); + break; + + case OSSO_ERROR: + g_debug ("Ordinary Error\n"); + break; + + case OSSO_INVALID: + g_debug ("At least one parameter is invalid\n"); + break; + + case OSSO_RPC_ERROR: + g_debug ("Osso RPC method returned an error\n"); + break; + + case OSSO_ERROR_NAME: + g_debug ("Error Name\n"); + break; + + case OSSO_ERROR_NO_STATE: + g_debug ("No state file found to read\n"); + break; + + case OSSO_ERROR_STATE_SIZE: + g_debug("The size of the given structure"); + g_debug(" is different from the saved size\n"); + break; + }; +}; + + +static WSDBusStatus ws_dbus_run_cb (WSDBusMethodData *method_data, gpointer data) + +{ + g_debug ("%s: Running cb for method %s\n", __FUNCTION__, + method_data->name); + + ws_dbus_cb cb; + osso_rpc_t osso_data; + + GArray *args = (GArray *) data; + + cb = (ws_dbus_cb) method_data->handler; + g_debug ("cb pointer address %p\n", cb); + + if (cb != NULL) + { + if (args->len == 0) + { + osso_data.type = WS_DBUS_TYPE_STRING; + osso_data.value.s = NULL; + g_array_append_val (args, osso_data); + } + + cb (NULL, data, method_data->user_data); + return OSSO_OK; + } + + else + { + g_debug ("DBUS: No callback defined for this function\n"); + return OSSO_ERROR; + }; +}; + +static gint ws_dbus_cb_handler (const gchar * interface, + const gchar * method, + GArray * arguments, + gpointer data, + osso_rpc_t * retval) + +{ + WSDBusMethodData *method_data; + GArray *dbus_method_data; + GQuark temp; + guint i; + dbus_method_data = (GArray *) data; + retval = NULL; + g_debug ("DBUS: Method: %s\n", method); + temp = g_quark_try_string (method); + + if (temp != 0) + + { + for (i=0; i < dbus_method_data->len; ++i) + + { + method_data = g_array_index (dbus_method_data, + WSDBusMethodData *, i); + + if (method_data->id == temp) + + { + g_debug ("DBUS: Running callback for %s\n", + method); + ws_dbus_run_cb (method_data, arguments); + }; + + }; + + } + + else + + { + g_debug ("Error in function %s, couldn't find the signal %s\n", + __FUNCTION__, method); + return OSSO_ERROR; + }; + + return OSSO_OK; +}; + +static void ws_dbus_fill_message (DBusMessage *msg, void *data) +{ + + guint i; + osso_rpc_t *data_unit; + GArray *data_bundle; + gpointer buffer; + + data_bundle = (GArray *) data; + + g_debug ("%s, number of fields: %d", __FUNCTION__, data_bundle->len); + + if (data_bundle->len > 255) + g_debug ("DBUS: Number of fields in message exceeds 255\n"); + + for (i=0;((ilen) && (i<255));++i) + { + data_unit = g_array_index (data_bundle, osso_rpc_t *, i); + + g_debug ("%s, type: %c, value: ", __FUNCTION__, data_unit->type); + + switch (data_unit->type) + { + case DBUS_TYPE_STRING: + buffer = &data_unit->value.s; + g_debug ("%s", data_unit->value.s); + break; + + case DBUS_TYPE_INT32: + buffer = &data_unit->value.i; + g_debug ("%d", data_unit->value.i); + break; + + case DBUS_TYPE_DOUBLE: + buffer = &data_unit->value.d; + g_debug ("%f", data_unit->value.d); + break; + + case DBUS_TYPE_BOOLEAN: + buffer = &data_unit->value.b; + g_debug ("%d", data_unit->value.b); + break; + }; + + if (data_unit->value.s != NULL) { + dbus_message_append_args (msg, + data_unit->type, buffer, + DBUS_TYPE_INVALID); + } + + else + if (data_bundle->len > 1) + g_debug ("One of the arguments is NULL, ommitting it"); + + }; + + g_debug ("DBUS: Added %d words\n", i); +}; + +void ws_dbus_add_remote_methods (GError *error, gpointer data, gpointer user_data) +{ + WSDBusData *ws_dbus_data = (WSDBusData *) user_data; + GArray *methods_list = (GArray *) data; + guint i=0; + + osso_rpc_t *temp; + + for (i = 0; i < methods_list->len; ++i) + { + temp = g_array_index (methods_list, osso_rpc_t *, i); + g_array_append_val (ws_dbus_data->remote_method_data, temp->value); + }; + + return; +}; + +WSDBusData * ws_dbus_create (gchar *name, gchar *version) + +{ + WSDBusData *temp; + + temp = (gpointer) g_try_malloc (sizeof (WSDBusData)); + + g_debug ("\nDBUS: "); + + if (temp == NULL) + { + g_debug ("Error in function %s - cannot allocate memory\n", + __FUNCTION__); + g_assert_not_reached(); + } + + else g_debug ("Memory allocation successful\n"); + + temp->name = g_strconcat (name, NULL); + temp->version = g_strconcat (version, NULL); + + temp->method_data = g_array_new (TRUE, TRUE, sizeof (WSDBusMethodData *)); + + //Adding callback for remote methods list + //ws_dbus_add_method (temp, "method_data", WS_DBUS_TYPE_STRING, WS_DBUS_TYPE_STRING); + //ws_dbus_set_cb (temp, "method_data", ws_dbus_add_remote_methods, NULL); + + return temp; +}; + +WSDBusStatus ws_dbus_config (WSDBusData * ws_dbus_data, + WSDBusConfig field, + gchar *value) + +{ + if (ws_dbus_data == NULL) + { + g_debug ("\nDBUS: Error in function %s - ws_dbus_data is NULL\n", + __FUNCTION__); + }; + + switch (field) + { + case WS_DBUS_CONFIG_SERVICE : + ws_dbus_data->service = g_strconcat (value, NULL); + break; + case WS_DBUS_CONFIG_OBJECT : + ws_dbus_data->object = g_strconcat (value, NULL); + break; + case WS_DBUS_CONFIG_IFACE : + ws_dbus_data->iface = g_strconcat (value, NULL); + break; + case WS_DBUS_CONFIG_REMOTE_SERVICE : + ws_dbus_data->remote_service = g_strconcat (value, NULL); + break; + case WS_DBUS_CONFIG_REMOTE_OBJECT : + ws_dbus_data->remote_object = g_strconcat (value, NULL); + break; + case WS_DBUS_CONFIG_REMOTE_IFACE : + ws_dbus_data->remote_iface = g_strconcat (value, NULL); + break; + }; + + return WS_DBUS_STATUS_OK; +}; + +WSDBusStatus ws_dbus_connect (WSDBusData * ws_dbus_data) + +{ + osso_return_t result; + + ws_dbus_data->context = osso_initialize (ws_dbus_data->name, + ws_dbus_data->version, + FALSE, + NULL); + osso_rpc_set_timeout (ws_dbus_data->context, 100); + + result = osso_rpc_set_cb_f(ws_dbus_data->context, + ws_dbus_data->service, + ws_dbus_data->object, + ws_dbus_data->iface, + ws_dbus_cb_handler, + ws_dbus_data->method_data); + + + g_debug ("\nWysy³anie danych metod\n"); + //sends methods list to remote receiver + //ws_dbus_send_method_data (ws_dbus_data); + + if (result == OSSO_OK) return WS_DBUS_STATUS_OK; + else return WS_DBUS_STATUS_ERROR; +}; + +void ws_dbus_destroy (WSDBusData * ws_dbus_data) + +{ + guint i; + + if (ws_dbus_data == NULL) + { + g_debug ("\nDBUS: Error in function %s - cannot free osso_context\n", + __FUNCTION__); + g_free (ws_dbus_data); + g_assert_not_reached(); + }; + + g_debug ("\nDBUS deinitialization by %s:\n---------------------------\n", + ws_dbus_data->service); + osso_deinitialize (ws_dbus_data->context); + g_debug ("| Deinitializing osso context |\n"); + if (ws_dbus_data->method_data != NULL) + { + for (i = 0; i < ws_dbus_data->method_data->len; ++i) + { + WSDBusMethodData *temp = + g_array_index(ws_dbus_data->method_data, + WSDBusMethodData *, i); + g_free (temp->data_types); + g_free (temp->name); + + g_free (temp); + }; + + g_array_free (ws_dbus_data->method_data, TRUE); + g_debug ("| Freeing callback pointers list |\n"); + }; + + g_free (ws_dbus_data->name); + g_free (ws_dbus_data->version); + g_free (ws_dbus_data->service); + g_free (ws_dbus_data->object); + g_free (ws_dbus_data->iface); + + g_free (ws_dbus_data->remote_service); + g_free (ws_dbus_data->remote_object); + g_free (ws_dbus_data->remote_iface); + +/* if (ws_dbus_data->remote_method_data != NULL) + { + for (i = 0; i < ws_dbus_data->remote_method_data->len; ++i) + { + g_free (g_array_index(ws_dbus_data->remote_method_data, + gchar*, i)); + }; + g_array_free (ws_dbus_data->remote_method_data, TRUE); + };*/ + + g_free (ws_dbus_data); + g_debug ("| Freeing WSDBusData structure |\n----------------------\n"); +}; + + +WSDBusStatus ws_dbus_set_cb (WSDBusData * ws_dbus_data, + gchar * method, + gpointer c_func, + gpointer user_data) + +{ + WSDBusMethodData *method_data; + GQuark temp; + guint i; + + temp = g_quark_try_string (method); + + if (temp == 0) + { + g_debug ("DBUS:\"%s\"- method not defined or invalid method name\n", + method); + return WS_DBUS_STATUS_ERROR; + } + + else + { + + for (i = 0; i < ws_dbus_data->method_data->len; ++i) + { + method_data = g_array_index (ws_dbus_data->method_data, + WSDBusMethodData *, + i); + + if (method_data->id == temp) + + { + method_data->handler = c_func; + method_data->user_data = user_data; + g_array_insert_val(ws_dbus_data->method_data, + i, + method_data); + g_array_remove_index (ws_dbus_data->method_data, + i+1); + }; + + }; + + }; + +// ws_dbus_send_method_data (ws_dbus_data); + + return WS_DBUS_STATUS_OK; +}; + +WSDBusStatus ws_dbus_add_method (WSDBusData * ws_dbus_data, gchar *method, ...) + +{ + WSDBusMethodData *method_data; + WSDBusDataType data_type; + GQuark temp; + gchar *buffer; + va_list arglist; + + temp = g_quark_try_string (method); + + if (temp == 0) + { + method_data = g_try_malloc (sizeof (WSDBusMethodData)); + + if (method_data != NULL) + { + va_start (arglist, method); + + method_data->id = g_quark_from_string (method); + method_data->name = g_strdup (method); + + data_type = va_arg (arglist, WSDBusDataType); + + method_data->data_types = g_strdup(""); + + while (data_type != WS_DBUS_TYPE_INVALID) + { + buffer = method_data->data_types; + + method_data->data_types = g_strdup_printf ("%s%c", + method_data->data_types, + (gchar) data_type ); + + g_free (buffer); + + data_type = va_arg (arglist, WSDBusDataType); + }; + + g_debug ("%d, %s, %s\n", method_data->id, method_data->name, method_data->data_types); + + va_end (arglist); + + g_array_append_val (ws_dbus_data->method_data, method_data); + } + + else g_debug ("DBUS: Failed to allocate memory for method data"); + + } + + else + { + g_debug ("DBUS:\"%s\"- method has already been registered\n", + method); + + return WS_DBUS_STATUS_ERROR; + }; + + return WS_DBUS_STATUS_OK; +}; + +WSDBusStatus ws_dbus_add_garray (GArray *data_bundle, GArray *strings) + +{ + osso_rpc_t *temp; + guint i; + + if (strings != NULL) + { + + for (i = 0; i < strings->len; ++i) + { + temp = g_try_malloc (sizeof (osso_rpc_t)); + temp->type = WS_DBUS_TYPE_STRING; + temp->value.s = g_array_index (strings, gchar *, i); + g_debug ("%d, %s", temp->type, temp->value.s); + g_array_append_val (data_bundle, temp); + }; + + return WS_DBUS_STATUS_OK; + + } + + else + { + printf ("\n%s - Error - GArray is NULL", __FUNCTION__); + return WS_DBUS_STATUS_ERROR; + }; + +}; + +WSDBusStatus ws_dbus_call_method (WSDBusData * ws_dbus_data, gchar *method, ...) + +{ + va_list arglist; + GArray *data_to_send; + osso_rpc_t *temp, *retval; + osso_return_t result; + GArray *temp_garray; + + data_to_send = g_array_new (TRUE, TRUE, sizeof (osso_rpc_t *)); + + va_start (arglist, method); + + while (1) + { + temp = g_try_malloc (sizeof (osso_rpc_t)); + + temp->type = va_arg (arglist, WSDBusDataType); + + g_debug ("Type: %c ", temp->type); + + if (temp->type == WS_DBUS_TYPE_INVALID) break; + + switch (temp->type) + { + case WS_DBUS_TYPE_STRING: + temp->value.s = va_arg (arglist, gchar *); + g_debug ("Value: %s\n", temp->value.s); + break; + case WS_DBUS_TYPE_INT: + temp->value.i = va_arg (arglist, gint); + g_debug ("Value: %d\n", temp->value.i); + break; + case WS_DBUS_TYPE_UINT: + temp->value.u = va_arg (arglist, guint); + g_debug ("Value: %d\n", temp->value.u); + break; + case WS_DBUS_TYPE_DOUBLE: + temp->value.d = va_arg (arglist, gdouble); + g_debug ("Value: %f\n", temp->value.d); + break; + case WS_DBUS_TYPE_BOOLEAN: + temp->value.b = va_arg (arglist, gboolean); + g_debug ("Value: %d\n", temp->value.b); + break; + case WS_DBUS_TYPE_GARRAY: + temp_garray = va_arg (arglist, GArray *); + ws_dbus_add_garray (data_to_send, + temp_garray); + g_debug ("Value: GArray of strings"); + break; + }; + g_debug ("Type: %c %d", temp->type, temp->value.i); + + if (temp->type != WS_DBUS_TYPE_GARRAY) + g_array_append_val (data_to_send, temp); + }; + + va_end (arglist); + + g_debug ("%s, method %s, added %d arguments", __FUNCTION__, + method, data_to_send->len); + + + retval = g_try_malloc (sizeof (osso_rpc_t)); + + if (retval == NULL) + { + g_debug("DBUS: Error in function %s:",__FUNCTION__); + g_debug("Couldn't allocate memory for message's return value\n"); + }; + + result = osso_rpc_run_with_argfill (ws_dbus_data->context, + ws_dbus_data->remote_service, + ws_dbus_data->remote_object, + ws_dbus_data->remote_iface, + method, + retval, + ws_dbus_fill_message, + data_to_send); + + g_debug ("\nDBUS: %s: ", __FUNCTION__); + + ws_dbus_libosso_errors (result); + + guint i; + + for (i = 0; i < data_to_send->len; ++i) + { + g_free (g_array_index(data_to_send, osso_rpc_t*,i)); + }; + + g_array_free (data_to_send, TRUE); + + if (result != OSSO_OK) + { + g_debug ("Error message: %s\n", retval->value.s); + osso_rpc_free_val (retval); + g_free (retval); + return WS_DBUS_STATUS_ERROR; + }; + + osso_rpc_free_val (retval); + g_free (retval); + return WS_DBUS_STATUS_OK; +}; + +WSDBusStatus ws_dbus_call_registered_method (WSDBusData * ws_dbus_data, gchar *method, ...) + +{ + va_list arglist; + guint i; + GArray *data_to_send; + osso_rpc_t *temp; + osso_return_t result; + osso_rpc_t *retval; + + gchar* data_types = ws_dbus_get_ptr2method ( + ws_dbus_data->remote_method_data, + method); + + g_debug ("\n%s\n", data_types); + + data_to_send = g_array_new (TRUE, TRUE, sizeof (osso_rpc_t *)); + + va_start (arglist, method); + + for (i = 0; i < strlen (data_types); ++i) + { + temp = g_try_malloc (sizeof (osso_rpc_t)); + + switch ((char) data_types[i]) + { + case WS_DBUS_TYPE_STRING: + temp->value.s = va_arg (arglist, gchar *); + break; + case WS_DBUS_TYPE_INT: + temp->value.i = va_arg (arglist, gint); + break; + case WS_DBUS_TYPE_UINT: + temp->value.u = va_arg (arglist, guint); + break; + case WS_DBUS_TYPE_DOUBLE: + temp->value.d = va_arg (arglist, gdouble); + break; + case WS_DBUS_TYPE_BOOLEAN: + temp->value.b = va_arg (arglist, gboolean); + break; + }; + + g_array_append_val (data_to_send, temp); + }; + + va_end (arglist); + + retval = g_try_malloc (sizeof (osso_rpc_t)); + + if (retval == NULL) + { + g_debug("DBUS: Error in function %s:",__FUNCTION__); + g_debug("Couldn't allocate memory for message's return value\n"); + }; + + result = osso_rpc_run_with_argfill (ws_dbus_data->context, + ws_dbus_data->remote_service, + ws_dbus_data->remote_object, + ws_dbus_data->remote_iface, + method, + retval, + ws_dbus_fill_message, + data_to_send); + g_debug ("\nDBUS: %s: ", __FUNCTION__); + + ws_dbus_libosso_errors (result); + + if (result != OSSO_OK) + { + g_debug ("Error message: %s\n", retval->value.s); + osso_rpc_free_val (retval); + g_free (retval); + return WS_DBUS_STATUS_ERROR; + }; + + osso_rpc_free_val (retval); + g_free (retval); + return WS_DBUS_STATUS_OK; + + return WS_DBUS_STATUS_OK; +}; + +/* +WSDBusStatus ws_dbus_run_method (WSDBusData * ws_dbus_data, gchar *method, ...) + +{ + va_list arglist; + guint i; + GArray *data_to_send; + osso_rpc_t *temp; + osso_return_t result; + osso_rpc_t *retval; + + gchar* method_data = ws_dbus_get_ptr2method ( + ws_dbus_data->method_data, + method); + + data_to_send = g_array_new (TRUE, TRUE, sizeof (osso_rpc_t *)); + + va_start (arglist, method); + + g_debug ("%p\n\n%p\n\n", method_data, method_data->data_types); + + for (i = 0; i < strlen (method_data->data_types); ++i) + { + temp = g_try_malloc (sizeof (osso_rpc_t)); + temp->type = method_data->data_types[i]; + + switch ((char) method_data->data_types[i]) + { + case WS_DBUS_TYPE_STRING: + temp->value.s = va_arg (arglist, gchar *); + break; + case WS_DBUS_TYPE_INT: + temp->value.i = va_arg (arglist, gint); + break; + case WS_DBUS_TYPE_SIGNAL: + case WS_DBUS_TYPE_UINT: + temp->value.u = va_arg (arglist, guint); + break; + case WS_DBUS_TYPE_DOUBLE: + temp->value.d = va_arg (arglist, gdouble); + break; + case WS_DBUS_TYPE_BOOLEAN: + temp->value.b = va_arg (arglist, gboolean); + break; + }; + + g_array_append_val (data_to_send, temp); + }; + + va_end (arglist); + + retval = g_try_malloc (sizeof (osso_rpc_t)); + + if (retval == NULL) + { + g_debug("DBUS: Error in function %s:",__FUNCTION__); + g_debug("Couldn't allocate memory for message's return value\n"); + }; + + result = osso_rpc_run_with_argfill (ws_dbus_data->context, + ws_dbus_data->remote_service, + ws_dbus_data->remote_object, + ws_dbus_data->remote_iface, + method, + retval, + ws_dbus_fill_message, + data_to_send); + g_debug ("\nDBUS: %s: ", __FUNCTION__); + + ws_dbus_libosso_errors (result); +registered_ + if (result != OSSO_OK) + { + g_debug ("Error message: %s\n", retval->value.s); + osso_rpc_free_val (retval); + g_free (retval); + return WS_DBUS_STATUS_ERROR; + }; + + osso_rpc_free_val (retval); + g_free (retval); + return WS_DBUS_STATUS_OK; + + return WS_DBUS_STATUS_OK; +}; +*/ + + +/*static void ws_dbus_fill_method_data (DBusMessage *msg, void *data) +{ + + guint i; + WSDBusMethodData *buffer; + GArray *temp; + + temp = (GArray *) data; + + for (i=0;((ilen) && (i<255));++i) + { + buffer = g_array_index (temp, WSDBusMethodData *, i); + + g_debug ("name: %s\ntypes: %s", buffer->name, buffer->data_types); + + return; + + dbus_message_append_args (msg, DBUS_TYPE_STRING, buffer->name, + DBUS_TYPE_STRING, buffer->data_types, + DBUS_TYPE_INVALID); + }; + g_debug ("DBUS: Added %d words\n", i); +}; + +WSDBusStatus ws_dbus_send_method_data (WSDBusData *ws_dbus_data) +{ + osso_return_t result; + osso_rpc_t *retval; + + retval = g_try_malloc (sizeof (osso_rpc_t)); + + if (retval == NULL) + { + g_debug("DBUS: Error in function %s:",__FUNCTION__); + g_debug(" Couldn't allocate memory for message's return value\n"); + }; + + result = osso_rpc_run_with_argfill (ws_dbus_data->context, + ws_dbus_data->remote_service, + ws_dbus_data->remote_object, + ws_dbus_data->remote_iface, + "method_data", + retval, + ws_dbus_fill_method_data, + ws_dbus_data->method_data); + + g_debug ("\nDBUS: %s: ", __FUNCTION__); + + ws_dbus_libosso_errors (result); + + if (result != OSSO_OK) + { + g_debug ("Error message: %s\n", retval->value.s); + osso_rpc_free_val (retval); + g_free (retval); + return WS_DBUS_STATUS_ERROR; + }; + + osso_rpc_free_val (retval); + g_free (retval); + return WS_DBUS_STATUS_OK; +};*/ diff --git a/src/gui/include/pc-instances.h b/src/gui/include/pc-instances.h new file mode 100644 index 0000000..5cf6b7d --- /dev/null +++ b/src/gui/include/pc-instances.h @@ -0,0 +1,79 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#ifndef _PC_INSTANCES_H_ +#define _PC_INSTANCES_H_ +#ifdef __cplusplus +extern "C" { +#endif + +// stadards headers +#include +#include +#include +// headers with unix types/functions - only for timers and files operations +#include +#include +#include +#include +#include +#include + +//------------------------------------------------------------------------------ +/** \brief Get comandline by which process in /proc tree was invoked. + * + * @param process describes which process from /proc tree we want to check. It + * should be only concrete directory from /proc nothing else. e.g.: /proc/self, + * /proc/8321 etc. Something like /proc or /proc/self is not good. + * @return string containing comandline which has invoked process. If NULL there + * were some problems, possibly parameter were wrong or ther is no such + * a process. + */ +char* get_process_cmdline(char* process); + +//------------------------------------------------------------------------------ +/** \brief Cut from commandline only program file name. + * + * @param cmdline commandline which from which we want to remove options. + * @return string with only program file name, or NULL if there was any problem + */ +char* get_process_program_file(char* cmdline); + +//------------------------------------------------------------------------------ +/** \brief Get file name containing programm executing by current process. + * + * @return file name of program or NULL if there were some problems. + */ +char* get_current_process_program_file(); + +//------------------------------------------------------------------------------ +/** \brief Check if there is another instance of current programm. + * + * @return integer telling how many processes were initiated with the same + * program as curent process. If it is 1, it means there is no other procces. + * If > 1 there is another instance. + */ +int is_already_running_this_application(); + + + +#ifdef __cplusplus +} /* extern "C" { */ +#endif +#endif /* _PC_INSTANCES_H_ */ diff --git a/src/gui/include/ws_gui.h b/src/gui/include/ws_gui.h new file mode 100644 index 0000000..66c9607 --- /dev/null +++ b/src/gui/include/ws_gui.h @@ -0,0 +1,277 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#ifndef _WS_GUI +#define _WS_GUI + +#ifdef __cplusplus +extern "C" { +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#define ZOOM_MIN 1.000000 +#define ZOOM_MAX 2.000000 +#define ZOOM_STEP 0.100000 +#define ZOOM_DEFAULT 1.300000 +#define PRESS_TIME 1.0 +#define HISTORY_LEN 5 +#define SCROLL_STEP_H 50 +#define SCROLL_STEP_V 20 +#define GCONF_PATH "/apps/maemo/WhiteStork/Dictionaries" +#define GCONF_CONF "/apps/maemo/WhiteStork/configuration" + + +#include +#include + +#define _(String) gettext (String) +#define WS_GUI_ABS(x) (((x)<0.0)?((-1)*(x)):(x)) + +void html_engine_unselect_all(HTMLEngine *e); +void html_engine_block_selection (HTMLEngine *e); +gboolean html_engine_is_selection_active (HTMLEngine *e); + +typedef struct WSGuiAppData WSGuiApp; + +enum +{ + COL_WORD = 0, + NUM_COLS +}; + + +/** \brief struct which manage layout of html (translation) area + * + * here are placed all components of application menu and popup menu + */ +struct HtmlLayout { +gchar *bg_color; +gchar *bg_image; +gchar *bg_font_color; + +gchar *th_color; +gchar *th_image; +gchar *th_font_color; + +gchar *td_color; +gchar *td_image; +gchar *td_font_color; +}; + +/** \brief struct which contains components of menu + * + * here are placed all components of application menu and popup menu + */ +struct WSGuiMenu { + /*application menu*/ + GtkWidget *ws_gui_main_menu; ///< application submenu + GtkWidget *ws_gui_menu_dictionaries; ///< dictionaries submenu (managing with the dictionary files) + GtkWidget *ws_gui_menu_load_dict; /// + + +#include +#include +#include +#include +#include + +#define TIMER_START TRUE +#define TIMER_STOP FALSE + + +/* added by Dariusz Wiechecki - HISA */ +void ws_gui_search_home_handler(GError *error, GArray *word, gpointer user_data); + +/*do dbusa*/ +/** \brief handle dbus signals + * + */ +void ws_gui_signal_hander (GError *error, GArray *words, gpointer user_data); + +/** \brief handle signal from dbus and updates progress bar(in order to caching) + * + */ +void ws_dbus_progress_bar(GError *error, GArray *words, gpointer user_data); + +/** \brief clean words list + * + */ +void ws_gui_clear_list (GtkListStore* list); + +/** \brief handle dbus signal and transfer words to the words list + * + */ +void ws_gui_dbus_return_words (GError *error, + GArray *words, + gpointer user_data); + +/** \brief handle dbus signal and convert message into readable text + * + */ +void ws_gui_dbus_return_translation (GError *error, + GArray *words, + gpointer user_data); + +/** \brief handle dbus signal and load extracted dictionary + * + */ +void ws_dbus_server_return_extracted_bzip(GError *error, + GArray *words, + gpointer user_data); + +/** \brief is used to free memory, which was allocated +* +*/ +void ws_gui_free_memory(gpointer user_data); + +/** \brief handle keys press signals (hardware keys in device) +* +*/ +gboolean hildon_key_press_listener (GtkWidget * widget, + GdkEventKey * keyevent, + gpointer user_data); + +/** \brief allow to hide words list from menu +* +*/ +void ws_gui_words_list_hide_from_menu(GtkCheckMenuItem *checkmenuitem, + gpointer user_data); + +/** \brief allow to hide words list from toolbar +* +*/ +void ws_gui_words_list_hide(GtkToggleButton *togglebutton, gpointer user_data); + +/** \brief add word to the words history +* +*/ +void ws_gui_history_add(char *new_word, gpointer user_data); + +/** \brief display translation of word stored in the history (if available) +* +*/ +void ws_gui_history_back(GtkButton *button, gpointer user_data); + +/** \brief display translation of word stored in the history (if available) +* +*/ +void ws_gui_history_next(GtkButton *button, gpointer user_data); + +/** \brief check history and disable buttons or uncheck checkbuttons + * + */ +void ws_gui_check_history(gpointer user_data); + +/** \brief creates model and view of words list + * + */ +GtkWidget * create_view_and_model (GArray *words_list, gpointer user_data); + +/** \brief creates words list and fill it with content + * + */ +GtkTreeModel * create_and_fill_model (GArray *words_list, gpointer user_data); + +/** \brief switch view between full screen and normal mode +* +*/ +void ws_gui_full_screen(GtkMenuItem *menuitem, gpointer user_data); + +/** \brief search for selected text in a dictionary +* +*/ +void ws_gui_popup_search(GtkMenuItem *menuitem, gpointer user_data); + +/** \brief allows to select whole text in translation (html) area +* +*/ +void ws_gui_html_select_all(GtkMenuItem *menuitem, gpointer user_data); + +/** \brief allows to copy text from translation (html) area into clipboard +* +*/ +void ws_gui_html_copy(GtkMenuItem *menuitem, gpointer user_data); + +/** \brief allows to paste text from the clipboard into find toolbar entry +* +*/ +void ws_gui_html_paste(GtkMenuItem *menuitem, gpointer user_data); + +/** \brief magnify translation (html) area +* +*/ +void ws_gui_html_zoom_in(GtkMenuItem *menuitem, gpointer user_data); + +/** \brief zoom out translation (html) area. +* +*/ +void ws_gui_html_zoom_out(GtkMenuItem *menuitem, gpointer user_data); + +/** \brief start search (sends typed word to the engine) +* +*/ +void ws_gui_search(GtkWidget * widget, gpointer user_data); + +/** \brief abort search +* +*/ +void ws_gui_search_stop(GtkButton *button, gpointer user_data); + +/** \brief used when user closes the application +* +*/ +void ws_gui_on_exit (GtkWidget *widget, GdkEvent *event, gpointer user_data); + +/** \brief used when user closes the application from menu +* +*/ +void ws_gui_menu_quit(GtkMenuItem *menuitem, gpointer user_data); + +/** \brief sets content of translation (html) area +* +*/ +void ws_gui_fill_html(char *html_context, gpointer user_data); + +/** \brief read current adjustment value + * + */ +void ws_gui_read_adjustment(gpointer user_data); + +/** \brief necessary to load images into translation (html) area + * + */ +void ws_gui_url_requested (GtkHTML *html, const char *url, + GtkHTMLStream *stream); + +/** \brief handles button press event + * + */ +gboolean ws_gui_button_press (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data); + +/** \brief handles button release event + * + */ +gboolean ws_gui_button_release (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data); + +/** \brief shows popup when user clicks and holds + * + */ +guint ws_gui_show_popup(gpointer user_data); + +/** \brief checks clipboard content + * + */ +void ws_gui_check_clipboard (GtkWidget *widget, gpointer user_data); + +/** \brief checks dictionaries availablity + * + */ +void ws_gui_dict_availablity(GtkMenuItem *menuitem, gpointer user_data); + +/** \brief allows to format html content + * + */ +gchar * format_html (gchar * received_string, gpointer user_data); + +/** \brief sets sensitivity of Bookmarks menu items + * + */ +void ws_gui_set_bookmarks_sensitivity(gpointer user_data); + +/** \brief sets sensitivity of Bookmarks menu items due to selection made + * + */ +void ws_gui_set_bookmark_menu_items(GtkMenuItem *menuitem, gpointer user_data); + +/** \brief sets sensitivity of menu items due to dictionary mode + * + */ +void ws_gui_read_active_dictionaries(gpointer user_data); + +void ws_gui_clear_array(GArray *history); + +void ws_gui_view_cursor_changed(GtkTreeView *treeview, gpointer user_data); + +void ws_gui_set_toolbar_avail(gpointer user_data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/gui/include/ws_gui_layout.h b/src/gui/include/ws_gui_layout.h new file mode 100644 index 0000000..41201a9 --- /dev/null +++ b/src/gui/include/ws_gui_layout.h @@ -0,0 +1,134 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#ifndef _WS_GUI_LAYOUT +#define _WS_GUI_LAYOUT + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** +* \brief create main window +* +*/ +void ws_gui_create_window(gpointer user_data); + +/** +* \brief create find toolbar +* +*/ +void ws_gui_create_find_toolbar(gpointer user_data); + +/** +* \brief create application menu +* +*/ +void ws_gui_create_main_menu (gpointer user_data); + +/** +* \brief create popup menu +* +*/ +void ws_gui_create_popup_menu (gpointer user_data); + +/** + * \brief select dictionaries to use + * + */ +void ws_gui_dictionary_chooser(GtkMenuItem *menuitem, gpointer user_data); + +/** + * \brief load new dictionary files + * + */ +void ws_gui_dictionary_loader(GtkMenuItem *menuitem, gpointer user_data); + +/** + * \brief load dictionary file using given filename + * + */ +gboolean ws_gui_load_dict(gchar *filename, gpointer user_data); + +/** + * \brief remove dictionary from application + * + */ +void ws_gui_dictionary_remover(GtkMenuItem *menuitem, gpointer user_data); + +/** + * \brief optimize dictionaries + * + */ +void ws_gui_dictionary_optimizer(GtkMenuItem *menuitem, gpointer user_data); + +/** + * \brief open bookmark window + * + */ +void ws_gui_dictionary_open_bookmark(GtkMenuItem *menuitem, gpointer user_data); + +/** + * \brief close bookmark window + * + */ +void ws_gui_dictionary_close_bookmark(GtkMenuItem *menuitem, + gpointer user_data); + +/** + * \brief add bookmark to bookmarks database + * + */ +void ws_gui_dictionary_add_bookmark(GtkMenuItem *menuitem, gpointer user_data); + +/** + * \brief remove bookmark from database + * + */ +void ws_gui_dictionary_remove_bookmark(GtkMenuItem *menuitem, + gpointer user_data); + +/** + * \brief display information about application + * + */ +void ws_gui_about_application(GtkMenuItem *menuitem, gpointer user_data); + +/** + * \brief creates Add Bookmark dialog window + * + */ +void ws_gui_add_bookmark_dialog(gpointer user_data); + +/** + * \brief creates Remove Bookmark dialog window + * + */ +void ws_gui_remove_bookmark_dialog(gpointer user_data); + +void ws_gui_list_full_dialog(GtkWidget *widget, GdkEventButton *event, gpointer user_data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/gui/makefile b/src/gui/makefile new file mode 100644 index 0000000..9d75e82 --- /dev/null +++ b/src/gui/makefile @@ -0,0 +1,50 @@ +CC = gcc +DEBUG = -g -Wall +EXECUTABLE = WhiteStork +INCLUDE_GUI = include +INCLUDE_DBUS_WRAPPER = ../../include +CFLAGS = `pkg-config --cflags gtk+-2.0 libgtkhtml-3.8 hildon-libs hildon-fm glib-2.0 libosso gconf-2.0` -I${INCLUDE_GUI} -I${INCLUDE_DBUS_WRAPPER} +LIBS = `pkg-config --libs gtk+-2.0 libgtkhtml-3.8 hildon-libs hildon-fm glib-2.0 libosso gconf-2.0` +APP_VER = unofficialbuild + +SOURCES = src +BINARIES = bin +MAIN_BINARIES = ../../bin + +${EXECUTABLE}: ${BINARIES}/ws_gui.o ${BINARIES}/ws_gui_callbacks.o ${BINARIES}/ws_gui_layout.o ${MAIN_BINARIES}/ws_dbus.o ${BINARIES}/pc-instances.o + @${CC} ${DEBUG} -o ${BINARIES}/${EXECUTABLE} ${BINARIES}/ws_gui.o ${BINARIES}/ws_gui_callbacks.o ${BINARIES}/ws_gui_layout.o ${BINARIES}/pc-instances.o ${MAIN_BINARIES}/ws_dbus.o ${LIBS} ${CFLAGS} + @cp ${BINARIES}/${EXECUTABLE} ${MAIN_BINARIES} + +${BINARIES}/ws_gui.o: ${SOURCES}/ws_gui.c ${INCLUDE_GUI}/ws_gui.h ${INCLUDE_GUI}/ws_gui_callbacks.h ${INCLUDE_GUI}/ws_gui_layout.h ${INCLUDE_DBUS_WRAPPER}/ws_dbus.h + @${CC} ${DEBUG} -c ${SOURCES}/ws_gui.c -o ${BINARIES}/ws_gui.o ${CFLAGS} + +${BINARIES}/ws_gui_callbacks.o: ${SOURCES}/ws_gui_callbacks.c ${INCLUDE_GUI}/ws_gui_callbacks.h ${INCLUDE_GUI}/ws_gui.h ${INCLUDE_DBUS_WRAPPER}/ws_dbus.h + @${CC} ${DEBUG} -c ${SOURCES}/ws_gui_callbacks.c -o ${BINARIES}/ws_gui_callbacks.o ${CFLAGS} + +${BINARIES}/ws_gui_layout.o: ${SOURCES}/ws_gui_layout.c ${INCLUDE_GUI}/ws_gui_layout.h ${INCLUDE_GUI}/ws_gui.h ${INCLUDE_DBUS_WRAPPER}/ws_dbus.h + @${CC} ${DEBUG} -DWS_VERSION=\"${APP_VER}\" -c ${SOURCES}/ws_gui_layout.c -o ${BINARIES}/ws_gui_layout.o ${CFLAGS} + +${BINARIES}/pc-instances.o: ${SOURCES}/pc-instances.c ${INCLUDE_GUI}/pc-instances.h + @${CC} ${DEBUG} -c ${SOURCES}/pc-instances.c -o ${BINARIES}/pc-instances.o ${CFLAGS} + +${MAIN_BINARIES}/ws_dbus.o: + cd ../dbus_wrapper && make + + +dyn: + ${BINARIES}/wsl_gui.o ${BINARIES}/wsl_gui_callbacks.o ${BINARIES}/wsl_gui_layout.o + ${CC} ${DEBUG} -shared -fPIC -o ${EXECUTABLE}.so ${BINARIES}/wsl_gui.o ${BINARIES}/wsl_gui_callbacks.o ${BINARIES}/wsl_gui_layout.o dbus/ws_dbus.o ${LIBS} ${CFLAGS} + +${BINARIES}/wsl_gui.o: ${SOURCES}/ws_gui.c ${INCLUDE_GUI}/ws_gui.h ${INCLUDE_GUI}/ws_gui_callbacks.h ${INCLUDE_GUI}/ws_gui_layout.h ${INCLUDE_DBUS_WRAPPER}/ws_dbus.h + ${CC} ${DEBUG} -fPIC -c ${SOURCES}/ws_gui.c -o ${BINARIES}/wsl_gui.o ${CFLAGS} + +${BINARIES}/wsl_gui_callbacks.o: ${SOURCES}/ws_gui_callbacks.c ${INCLUDE_GUI}/ws_gui_callbacks.h ${INCLUDE_GUI}/ws_gui.h ${INCLUDE_DBUS_WRAPPER}/ws_dbus.h + ${CC} ${DEBUG} -fPIC -c ${SOURCES}/ws_gui_callbacks.c -o ${BINARIES}/wsl_gui_callbacks.o ${CFLAGS} + +${BINARIES}/wsl_gui_layout.o: ${SOURCES}/ws_gui_layout.c ${INCLUDE_GUI}/ws_gui_layout.h ${INCLUDE_GUI}/ws_gui.h ${INCLUDE_DBUS_WRAPPER}/ws_dbus.h + ${CC} ${DEBUG} -fPIC -c ${SOURCES}/ws_gui_layout.c -o ${BINARIES}/wsl_gui_layout.o ${CFLAGS} + + +clean: + rm -f ${BINARIES}/* + @echo "done" diff --git a/src/gui/src/pc-instances.c b/src/gui/src/pc-instances.c new file mode 100644 index 0000000..38a96c1 --- /dev/null +++ b/src/gui/src/pc-instances.c @@ -0,0 +1,169 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#include + +//------------------------------------------------------------------------------ +/** \brief Get comandline by which process in /proc tree was invoked. + * + * @param process describes which process from /proc tree we want to check. It + * should be only concrete directory from /proc nothing else. e.g.: /proc/self, + * /proc/8321 etc. Something like /proc or /proc/self is not good. + * @return string containing comandline which has invoked process. If NULL there + * were some problems, possibly parameter were wrong or ther is no such + * a process. + */ +char* get_process_cmdline(char* process) +{ + // build final filename to read + const char* postfix = "/cmdline"; + int arg_len = strlen(process); + char* tmp = (char*)malloc((size_t)(arg_len+9)); + tmp[arg_len+8] = '\0'; + sprintf(tmp,"%s%s",process,postfix); + //printf("Process to check: %s\n",tmp); + + // open file to read + int file = open(tmp, O_RDONLY); + free(tmp); tmp = 0; + if(-1 == file) + { + return (char*)0; + } + + int length = 512; + + // buffer for data from /proc/self/cmdline file + char* buffer = (char*)malloc(length + 1); + + // read file to buffer + int readed = read(file, buffer, length); + close(file); + if(readed == length) + { + free(buffer); + return (char*)0; + } + buffer[length] = '\0'; + + //printf("%s() returned finaly: %s\n",__FUNCTION__,buffer); + return buffer; +} +//------------------------------------------------------------------------------ +/** \brief Cut from commandline only program file name. + * + * @param cmdline commandline which from which we want to remove options. + * @return string with only program file name, or NULL if there was any problem + */ +char* get_process_program_file(char* cmdline) +{ + int start = 0; + int stop = 0; + // find first space in buffer (to remove optional options etc.) + while(cmdline[stop] && cmdline[stop] != ' ') + { + ++stop; + } + cmdline[stop] = '\0'; + + // find last "/" to remove directories + start = stop; + while((start>0) && (cmdline[start] != '/')) + { + --start; + } + if(cmdline[start] == '/') + { + ++start; + } + + // cut only needed fragment of buffer + if(start == stop) + { + return (char*)0; + } + + char* result = (char*)malloc(stop - start + 1); + memcpy(result, cmdline + start, stop - start + 1); + return result; +} +//------------------------------------------------------------------------------ +/** \brief Get file name containing program executing by current process. + * + * @return file name of program or NULL if there were some problems. + */ +char* get_current_process_program_file() +{ + char* cmd = get_process_cmdline("/proc/self"); + if(!cmd) + { + return (char*)0; + } + char* name = get_process_program_file(cmd); + free(cmd); cmd = 0; + + return name; +} +//------------------------------------------------------------------------------ +/** \brief Check if there is another instance of current programm. + * + * @return integer telling how many processes were initiated with the same + * program as curent process. If it is 1, it means there is no other procces. + * If > 1 there is another instance. + */ +int is_already_running_this_application() +{ + char* app = get_current_process_program_file(); + int count = 0; + + struct dirent* entry; + DIR* dir = opendir("/proc"); + struct stat st; + + char path[512]; + sprintf(path,"%s","/proc/"); + char* tmp = path + 6; + + while((entry = readdir(dir)) != NULL) + { + sprintf(tmp,"%s",entry->d_name); + lstat(path,&st); + + if(S_ISDIR(st.st_mode)) + { + char* cmd = get_process_cmdline(path); + if(!cmd) continue; + char* name = get_process_program_file(cmd); + free(cmd); cmd = 0; + if(!name) continue; + //printf("%s: next programm: %s\n",app,name); + + if(strcmp(app,name) == 0) + { + ++count; + } + + free(name); name = 0; + } + } + closedir(dir); dir = NULL; + free(app); app = 0; + return count; +} +//------------------------------------------------------------------------------ diff --git a/src/gui/src/ws_gui.c b/src/gui/src/ws_gui.c new file mode 100644 index 0000000..11b1e6f --- /dev/null +++ b/src/gui/src/ws_gui.c @@ -0,0 +1,185 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#include +#include +#include + +#include + +//int ws_gui_init(int argc, char *argv[]) +int main(int argc, char *argv[]) +{ + gtk_init(&argc, &argv); + + //localization + setlocale(LC_ALL, ""); + bindtextdomain("whitestork", "/usr/share/locale"); + bind_textdomain_codeset("whitestork", "UTF-8"); + textdomain("whitestork"); + + if (strcmp(_("ws_check"), "ws_check") == 0) + { + setlocale(LC_ALL, "en_GB"); + bindtextdomain("whitestork", "/usr/share/locale"); + bind_textdomain_codeset("whitestork", "UTF-8"); + textdomain("whitestork"); + } + + + WSGuiApp *ws_gui_app; + ws_gui_app = (WSGuiApp*)g_malloc(sizeof(WSGuiApp)); + + //memory allocation + ws_gui_app->ws_gui_w_list = + (struct WSGuiList*)g_malloc(sizeof(struct WSGuiList)); + ws_gui_app->ws_gui_menu = + (struct WSGuiMenu*)g_malloc(sizeof(struct WSGuiMenu)); + + //gonf + ws_gui_app->client = gconf_client_get_default(); + + ws_gui_create_window(ws_gui_app); + ws_gui_read_adjustment(ws_gui_app); + + + //dbus wrapper + ws_gui_app->dbus_data = ws_dbus_create ("WhiteStorkGui", "v1.0"); + + ws_dbus_config (ws_gui_app->dbus_data, + WS_DBUS_CONFIG_SERVICE, + "org.maemo.WhiteStorkGui"); + ws_dbus_config (ws_gui_app->dbus_data, + WS_DBUS_CONFIG_OBJECT, + "/org/maemo/WhiteStorkGui"); + ws_dbus_config (ws_gui_app->dbus_data, + WS_DBUS_CONFIG_IFACE, + "org.maemo.WhiteStorkGui"); + ws_dbus_config (ws_gui_app->dbus_data, + WS_DBUS_CONFIG_REMOTE_SERVICE, + "org.maemo.WhiteStorkManager"); + ws_dbus_config (ws_gui_app->dbus_data, + WS_DBUS_CONFIG_REMOTE_OBJECT, + "/org/maemo/WhiteStorkManager"); + ws_dbus_config (ws_gui_app->dbus_data, + WS_DBUS_CONFIG_REMOTE_IFACE, + "org.maemo.WhiteStorkManager"); + + + ws_dbus_add_method (ws_gui_app->dbus_data, + "return_words", + WS_DBUS_TYPE_GARRAY, + WS_DBUS_TYPE_INVALID); + + ws_dbus_add_method (ws_gui_app->dbus_data, + "return_translations", + WS_DBUS_TYPE_STRING, + WS_DBUS_TYPE_INVALID); + + ws_dbus_add_method (ws_gui_app->dbus_data, + "return_extracted_dict", + WS_DBUS_TYPE_STRING, + WS_DBUS_TYPE_INVALID); + + ws_dbus_add_method (ws_gui_app->dbus_data, + "update_progressbar", + WS_DBUS_TYPE_DOUBLE, + WS_DBUS_TYPE_INVALID); + + ws_dbus_add_method (ws_gui_app->dbus_data, + "signal", + WS_DBUS_TYPE_SIGNAL, + WS_DBUS_TYPE_INVALID); + + ws_dbus_add_method (ws_gui_app->dbus_data, + "search_home_applet", + WS_DBUS_TYPE_STRING, + WS_DBUS_TYPE_INVALID); + + ws_dbus_set_cb (ws_gui_app->dbus_data, + "return_words", + ws_gui_dbus_return_words, + ws_gui_app); + + ws_dbus_set_cb (ws_gui_app->dbus_data, + "return_translations", + ws_gui_dbus_return_translation, + ws_gui_app); + ws_dbus_set_cb (ws_gui_app->dbus_data, + "return_extracted_dict", + ws_dbus_server_return_extracted_bzip, + ws_gui_app); + ws_dbus_set_cb (ws_gui_app->dbus_data, + "update_progressbar", + ws_dbus_progress_bar, + ws_gui_app); + ws_dbus_set_cb (ws_gui_app->dbus_data, + "signal", + ws_gui_signal_hander, + ws_gui_app); + //hisa + ws_dbus_set_cb (ws_gui_app->dbus_data, + "search_home_applet", + ws_gui_search_home_handler, + ws_gui_app); + + ws_dbus_connect (ws_gui_app->dbus_data); + + //setting the clipboard + ws_gui_app->ws_gui_clipboard = + gtk_widget_get_clipboard (GTK_WIDGET(ws_gui_app->ws_gui_html), + GDK_SELECTION_CLIPBOARD); + + //connecting the signals + g_signal_connect(G_OBJECT (ws_gui_app->ws_gui_w_list->ws_gui_view), + "cursor-changed", + G_CALLBACK (ws_gui_view_cursor_changed), + ws_gui_app); + + + g_signal_connect(G_OBJECT(ws_gui_app->ws_gui_hildon_window), + "key-press-event", + G_CALLBACK(hildon_key_press_listener), + ws_gui_app); + g_signal_connect(G_OBJECT(ws_gui_app->ws_gui_html), + "button-press-event", + G_CALLBACK(ws_gui_button_press), + ws_gui_app); + g_signal_connect(G_OBJECT(ws_gui_app->ws_gui_html), + "button-release-event", + G_CALLBACK(ws_gui_button_release), + ws_gui_app); + + g_signal_connect(G_OBJECT(ws_gui_app->ws_gui_list_eventbox), + "button-press-event", + G_CALLBACK(ws_gui_list_full_dialog), + ws_gui_app); + g_signal_connect(G_OBJECT(ws_gui_app->ws_gui_hildon_window), + "delete-event", + G_CALLBACK(ws_gui_on_exit), + ws_gui_app); + + ws_dbus_notify(ws_gui_app->dbus_data, + WS_DBUS_ERROR_UNKNOWN); + + gtk_main(); + + return 0; +} + diff --git a/src/gui/src/ws_gui_callbacks.c b/src/gui/src/ws_gui_callbacks.c new file mode 100644 index 0000000..162b6c4 --- /dev/null +++ b/src/gui/src/ws_gui_callbacks.c @@ -0,0 +1,2354 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#include +#include +#include +#include + +/** \brief show how much time did take a callback of another function + * + */ +static double timer(gboolean start, gchar* message) +{ + static GArray* stack = NULL; + static gboolean first_run = TRUE; + static struct timeval actual_time; + static struct timeval last_time; + static struct timeval result; + static double seconds = 0.0; + if(first_run) + { + first_run = FALSE; + stack = g_array_new(TRUE, TRUE, sizeof(struct timeval)); + }; + // things to do on the beggining of function's work + if (start) + { + g_debug("XDXF->%s() start counting time for function '%s()'.\n", + __FUNCTION__,message); + g_array_prepend_val(stack, actual_time); + gettimeofday(&g_array_index(stack, struct timeval, 0),NULL); + return -1.0; + } + // we just want to end some timer - print some information + //about working time; + else { + gettimeofday(&actual_time,NULL); + last_time = g_array_index(stack, struct timeval, 0); + g_array_remove_index(stack, 0); + + if (actual_time.tv_usec < last_time.tv_usec) { + int nsec = (last_time.tv_usec - + actual_time.tv_usec) / 1000000 + 1; + last_time.tv_usec -= 1000000 * nsec; + last_time.tv_sec += nsec; + } + if (actual_time.tv_usec - last_time.tv_usec > 1000000) { + int nsec = (last_time.tv_usec - + actual_time.tv_usec) / 1000000; + last_time.tv_usec += 1000000 * nsec; + last_time.tv_sec -= nsec; + } + result.tv_sec = actual_time.tv_sec - last_time.tv_sec; + result.tv_usec = actual_time.tv_usec - last_time.tv_usec; + seconds = (((double)(result.tv_usec)) / 1e6) + + ((double)(result.tv_sec)); + + g_debug("XDXF->%s() function \'%s()\' was working for: %g [s] " + "or %ld [us].\n", + __FUNCTION__, + message,seconds, + ((long)(result.tv_sec*1e6)+(result.tv_usec))); + // stack is empty so we delete everything + if(stack->len == 0) + { + g_array_free(stack, TRUE); + first_run = TRUE; + } + return seconds; + } + return -2.0; +} + + +/** this function handles signals from dbus; it is called +when there are any messages from other modules + * + * @param error - error message recived from DBUS + * @param words - array with recived data structure + * @param user_data - pointer to data structure + * @return + */ +void ws_gui_signal_hander (GError *error, GArray *words, gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + osso_rpc_t osss_data; + osss_data = g_array_index (words, osso_rpc_t, 0); + + switch(osss_data.value.i) + { + case WS_DBUS_ERROR_ENGINE_NOT_FOUND: + { + ws_gui_app->ws_message_dialog = + gtk_message_dialog_new( + GTK_WINDOW(ws_gui_app->ws_gui_hildon_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("ws_ni_error_occured")); + gtk_widget_show_all(ws_gui_app->ws_message_dialog); + + g_signal_connect_swapped( + GTK_OBJECT (ws_gui_app->ws_message_dialog), + "response", + G_CALLBACK (gtk_main_quit), + ws_gui_app); + break; + } + + case WS_DBUS_ERROR_FILE_NOT_FOUND: + { + ws_gui_app->ws_message_dialog = + gtk_message_dialog_new( + GTK_WINDOW(ws_gui_app->ws_gui_hildon_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("ws_ni_no_dictionary_available")); + + gtk_widget_show_all(ws_gui_app->ws_message_dialog); + + GArray *tmp; + tmp = g_array_new(TRUE, TRUE, sizeof(gchar*)); + gtk_list_store_clear( + ws_gui_app->ws_gui_w_list->ws_gui_store); + ws_gui_app->ws_gui_w_list->ws_gui_model = + create_and_fill_model(tmp, ws_gui_app); + ws_gui_fill_html(" ", ws_gui_app); + ws_gui_app->html_flag = FALSE; + + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_hildon_find_toolbar), + FALSE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_search), + FALSE); + + if (gtk_dialog_run( + GTK_DIALOG(ws_gui_app->ws_message_dialog)) + == GTK_RESPONSE_OK) + { + gtk_widget_destroy( + ws_gui_app->ws_message_dialog); + } + break; + } + + case WS_DBUS_INFO_CACHING: + { + ws_gui_app->ws_gui_banner_caching = + hildon_banner_show_progress( + GTK_WIDGET(ws_gui_app->ws_gui_hildon_window), + NULL, + _("ws_pb_caching")); + ws_gui_app->caching_flag = TRUE; + hildon_banner_set_fraction( + HILDON_BANNER(ws_gui_app->ws_gui_banner_caching), + 0.0); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_hildon_find_toolbar), + FALSE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_search), + FALSE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_bookmarks), + FALSE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_w_list->ws_gui_view), + FALSE); + + break; + } + + case WS_DBUS_INFO_CACHING_FINISHED: + { + gtk_widget_destroy( + GTK_WIDGET(ws_gui_app->ws_gui_banner_caching)); + ws_gui_app->caching_flag = FALSE; + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_hildon_find_toolbar), + TRUE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_search), + TRUE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_bookmarks), + TRUE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_w_list->ws_gui_view), + TRUE); + + break; + } + + case WS_DBUS_ERROR_DICTIONARY_NOT_LOAD: + { + if (ws_gui_app->ws_gui_history_cur_pos >= 0 && + ws_gui_app->ws_gui_history_cur_pos <=HISTORY_LEN) + { + g_array_remove_index(ws_gui_app->ws_gui_history, + ws_gui_app->ws_gui_history_cur_pos); + } + + ws_gui_app->ws_message_dialog = gtk_message_dialog_new( + GTK_WINDOW(ws_gui_app->ws_gui_hildon_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("ws_ni_dictionary_unavailable")); + gtk_widget_show_all(ws_gui_app->ws_message_dialog); + if (gtk_dialog_run( + GTK_DIALOG(ws_gui_app->ws_message_dialog)) + == GTK_RESPONSE_OK) + { + gtk_widget_destroy(ws_gui_app->ws_message_dialog); + } + break; + } + + case WS_DBUS_BOOKMARKS_ADDED_OK: + { + gtk_infoprint(GTK_WINDOW( + ws_gui_app->ws_gui_hildon_window), + _("ws_ni_bookmark_added")); + break; + } + + case WS_DBUS_BOOKMARKS_REMOVED_OK: + { + gtk_infoprint(GTK_WINDOW( + ws_gui_app->ws_gui_hildon_window), + _("ws_ni_bookmark_removed")); + break; + } + + case WS_DBUS_BOOKMARKS_ADDED_FAIL: + { + gtk_infoprint(GTK_WINDOW( + ws_gui_app->ws_gui_hildon_window), + _("ws_ni_bookmark_not_added")); + break; + } + + case WS_DBUS_BOOKMARKS_REMOVED_FAIL: + { + gtk_infoprint(GTK_WINDOW( + ws_gui_app->ws_gui_hildon_window), + _("ws_ni_bookmark_not_removed")); + break; + } + + case WS_DBUS_LOAD_BOOKMARK_FAILED: + { + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_bookmarks), + FALSE); + ws_gui_app->bookmark_avail = FALSE; + + ws_gui_app->ws_message_dialog = + gtk_message_dialog_new( + GTK_WINDOW(ws_gui_app->ws_gui_hildon_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("ws_ni_bookmarks_unavailable")); + + if (gtk_dialog_run( + GTK_DIALOG(ws_gui_app->ws_message_dialog)) + == GTK_RESPONSE_OK) + { + gtk_widget_destroy( + ws_gui_app->ws_message_dialog); + } + + + break; + } + case WS_DBUS_EXTRACT_FILE: + { + ws_gui_app->ws_gui_banner_extracting = + hildon_banner_show_animation( + GTK_WIDGET(ws_gui_app->ws_gui_hildon_window), + NULL, + _("ws_pb_extracting")); + + ws_gui_app->caching_flag = TRUE; + + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_hildon_find_toolbar), + FALSE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_search), + FALSE); + + break; + } + + case WS_DBUS_EXTRACT_FILE_FINISHED: + { + gtk_widget_destroy( + GTK_WIDGET(ws_gui_app->ws_gui_banner_extracting)); + + ws_gui_app->caching_flag = FALSE; + + gtk_infoprint(GTK_WINDOW( + ws_gui_app->ws_gui_hildon_window), + _("ws_ni_dictionary_added")); + + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_hildon_find_toolbar), + TRUE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_search), + TRUE); + + break; + } + + case WS_DBUS_WORDS_LIST_FULL: + { + + gtk_widget_show(GTK_WIDGET(ws_gui_app->ws_gui_list_hbox)); + break; + } + + case WS_DBUS_WORDS_LIST_FINISHED: + { + gtk_widget_hide(GTK_WIDGET(ws_gui_app->ws_gui_banner_list_searching)); + break; + } + + case WS_DBUS_TRANSLATION_FINISHED: + { + gtk_widget_hide(ws_gui_app->ws_gui_banner_translation_loading); + break; + } + + case WS_DBUS_WORDS_LIST_STARTED: + { + gtk_widget_show(GTK_WIDGET(ws_gui_app->ws_gui_banner_list_searching)); + break; + } + + case WS_DBUS_TRANSLATION_STARTED: + { + gtk_widget_show(ws_gui_app->ws_gui_banner_translation_loading); + break; + } + + } +} + + +/* added by Dariusz Wiechecki - HISA */ +void ws_gui_search_home_handler(GError *error, GArray *word, gpointer user_data) +{ + g_debug("->%s", __FUNCTION__); + WSGuiApp *data = (WSGuiApp*) user_data; + osso_rpc_t* osso_data = NULL; + + + //get the word passed by dbus + osso_data = &g_array_index (word, osso_rpc_t, 0); + + //free memory used by last searched word + gchar* tmp = NULL; + tmp = g_strdup(osso_data->value.s + 11); + + g_object_set(G_OBJECT(data->ws_gui_hildon_find_toolbar), + "prefix", + tmp, + NULL); + ws_gui_search(NULL, data); +} + +/** this function handles signals from dbus; it is called when progress bar + status has been changed + * + * @param error - error message recived from DBUS + * @param words - array with recived data structure + * @param user_data - pointer to data structure + * @return + */ +void ws_dbus_progress_bar(GError *error, GArray *words, gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + osso_rpc_t osss_data; + osss_data = g_array_index (words, osso_rpc_t, 0); + double progress = osss_data.value.d; + if (ws_gui_app->caching_flag == TRUE) + { + hildon_banner_set_fraction( + HILDON_BANNER(ws_gui_app->ws_gui_banner_caching), + progress); + } +} + +/** this function clean GtkListStore row by row + * + * @param list - GtkListStore to be remoeved + * @return + */ +void ws_gui_clear_list (GtkListStore* list) +{ + GtkTreeIter iter; + gboolean tmp; + + tmp = gtk_tree_model_get_iter_first( + GTK_TREE_MODEL(list), + &iter); + + while (tmp == TRUE) + { + tmp = gtk_list_store_remove(list, &iter); + + } +} + + +/** this function handles signal from dbus and transfer recived +(found in a dictionary) words to the words list + * + * @param error - error message recived from DBUS + * @param words - array with recived data structure + * @param user_data - pointer to data structure + * @return + */ +void ws_gui_dbus_return_words (GError *error, GArray *words, gpointer user_data) +{ + timer(TIMER_START, (gchar*)__FUNCTION__); + guint i; + osso_rpc_t data; + + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + g_signal_handlers_block_by_func(G_OBJECT + (ws_gui_app->ws_gui_w_list->ws_gui_view), + G_CALLBACK (ws_gui_view_cursor_changed), + ws_gui_app); + + + GArray *tmp; + tmp = g_array_new(TRUE, TRUE, sizeof(gchar*)); + gchar *tmp_word; + + for (i=0;ilen;++i) + { + data = g_array_index (words, osso_rpc_t, i); + tmp_word = g_strdup(data.value.s); + g_array_append_val(tmp, tmp_word); + } + + g_assert(ws_gui_app->ws_gui_banner_list_searching); + //gtk_widget_hide(GTK_WIDGET(ws_gui_app->ws_gui_banner_list_searching)); + + ws_gui_app->loading = FALSE; + ws_gui_set_toolbar_avail(ws_gui_app); + + //ws_gui_app->ws_gui_banner_flag = FALSE; + + //ws_gui_clear_list(ws_gui_app->ws_gui_w_list->ws_gui_store); + + + ws_gui_app->ws_gui_w_list->ws_gui_model = + create_and_fill_model(tmp, ws_gui_app); + + if (ws_gui_app->history_flag == TRUE) + { + + GValue value = { 0, }; + GtkTreeIter tmp_iter; + gchar *pattern; + gboolean keep_searching = TRUE; + + if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL( + ws_gui_app->ws_gui_w_list->ws_gui_model), &tmp_iter) == TRUE) + { + + pattern = strdup(g_array_index(ws_gui_app->ws_gui_history, + gchar*, + ws_gui_app->ws_gui_history_cur_pos)); + + gtk_tree_model_get_value(GTK_TREE_MODEL( + ws_gui_app->ws_gui_w_list->ws_gui_model), + &tmp_iter, + COL_WORD, + &value); + + if ((g_value_get_string (&value) != NULL) && + (strcmp(((gchar *)g_value_get_string (&value)), + pattern) == 0)) + { + gtk_tree_selection_select_iter( + ws_gui_app->ws_gui_w_list->ws_gui_selection, + &tmp_iter); + + } + else + { + while (gtk_tree_model_iter_next(GTK_TREE_MODEL + (ws_gui_app->ws_gui_w_list->ws_gui_model), + &tmp_iter) == TRUE && keep_searching == TRUE) + { + gtk_tree_model_get_value(GTK_TREE_MODEL( + ws_gui_app->ws_gui_w_list->ws_gui_model), + &tmp_iter, + COL_WORD, + &value); + + if ((g_value_get_string (&value) != NULL) && + (strcmp(((gchar *)g_value_get_string (&value)), + pattern) == 0)) + { + gtk_tree_model_get_iter_from_string ( + GTK_TREE_MODEL( + ws_gui_app->ws_gui_w_list->ws_gui_model), + &tmp_iter, + g_array_index( + ws_gui_app->ws_gui_history_iter, + gchar*, + ws_gui_app->ws_gui_history_cur_pos)); + + gtk_tree_selection_select_iter( + ws_gui_app->ws_gui_w_list->ws_gui_selection, + &tmp_iter); + + keep_searching = FALSE; + } + } + } + } + g_free(pattern); + + ws_gui_app->history_flag = FALSE; + ws_dbus_client_find_translation(ws_gui_app->dbus_data, + g_array_index(ws_gui_app->ws_gui_history, + gchar*, + ws_gui_app->ws_gui_history_cur_pos)); + + ws_gui_app->html_flag = TRUE; + g_value_unset (&value); + } + + + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Dlugosc tempa to: %d", tmp->len); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "w tempie mamy: %s", tmp_word); + //if (&& ws_gui_app->stop_clicked != TRUE ) + + if ((tmp->len == 0 || tmp_word == NULL) && ws_gui_app->stop_clicked != TRUE ) + { + gtk_infoprint(GTK_WINDOW(ws_gui_app->ws_gui_hildon_window), + _("ws_ni_no_words_found")); + + //ws_gui_fill_html(" ", ws_gui_app); + //ws_gui_app->html_flag = FALSE; + g_free(ws_gui_app->last_word); + ws_gui_app->last_word = NULL; + } + + g_signal_handlers_unblock_by_func(G_OBJECT( + ws_gui_app->ws_gui_w_list->ws_gui_view), + G_CALLBACK (ws_gui_view_cursor_changed), + ws_gui_app); + + for (i=0;ilen;++i) + { + g_free(g_array_index(tmp, gchar* , i)); + } + g_array_free(tmp, TRUE); + + timer(TIMER_STOP, (gchar*)__FUNCTION__); +} + +/** this function handles signal from dbus and send recived data to +the translation area + * + * @param error - error message recived from DBUS + * @param words - array with recived data structure + * @param user_data - pointer to data structure + * @return + */ +void ws_gui_dbus_return_translation (GError *error, + GArray *words, + gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + gchar *html_content = NULL; + osso_rpc_t data; + + data = g_array_index (words, osso_rpc_t, 0); + + html_content = format_html(data.value.s, ws_gui_app); + ws_gui_fill_html(html_content, ws_gui_app); + g_free(html_content); + ws_gui_app->html_flag = TRUE; + + //gtk_widget_hide(ws_gui_app->ws_gui_banner_translation_loading); + ws_gui_app->loading = FALSE; + ws_gui_set_toolbar_avail(ws_gui_app); + +} + +/** this function handles signal from dbus and send recived data to +the translation area + * + * @param error - error message recived from DBUS + * @param words - array with recived data structure + * @param user_data - pointer to data structure + * @return + */ +void ws_dbus_server_return_extracted_bzip(GError *error, + GArray *words, + gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + osso_rpc_t data; + + data = g_array_index (words, osso_rpc_t, 0); + + if (data.value.s[0] == '\0') + { + gtk_infoprint(GTK_WINDOW( + ws_gui_app->ws_gui_hildon_window), + _("ws_ni_dictionary_not_added")); + } + else + { + if (ws_gui_load_dict(data.value.s, ws_gui_app) == TRUE) + { + + } + } +} + +/** +* this function allows to free allocated memory +* +* @param user_data - pointer to data structure +*/ +void ws_gui_free_memory(gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + guint i = 0; + for (i = 0; iws_gui_history->len; ++i) + { + g_free(g_array_index(ws_gui_app->ws_gui_history, gchar *, i)); + } + g_array_free(ws_gui_app->ws_gui_history, TRUE); + + for (i = 0; iws_gui_history_list->len; ++i) + { + g_free(g_array_index(ws_gui_app->ws_gui_history_list, gchar *, i)); + } + g_array_free(ws_gui_app->ws_gui_history_list, TRUE); + + for (i = 0; iws_gui_history_iter->len; ++i) + { + g_free(g_array_index(ws_gui_app->ws_gui_history_iter, gchar *, i)); + } + g_array_free(ws_gui_app->ws_gui_history_iter, TRUE); + + + pango_font_description_free(ws_gui_app->p); + + g_string_free(ws_gui_app->raw_translation, TRUE); + g_free(ws_gui_app->last_word); + g_free(ws_gui_app->ws_gui_w_list); + g_free(ws_gui_app->ws_gui_menu); + g_free(ws_gui_app); +} + +/** this function handle press signals (keyboard) + * + * @param widget + * @param keyevent + * @param user_data - ponter to data structure + * @return TRUE to stop other handlers from being invoked for the event. + FALSE to propagate the event further. + */ +gboolean hildon_key_press_listener (GtkWidget * widget, + GdkEventKey * keyevent, + gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + switch ((guint)(keyevent->keyval)) { + case HILDON_HARDKEY_UP: + { + gtk_container_set_focus_vadjustment( + GTK_CONTAINER(ws_gui_app->ws_gui_scrolledwindow_left), + gtk_scrolled_window_get_vadjustment( + GTK_SCROLLED_WINDOW( + ws_gui_app->ws_gui_scrolledwindow_left))); + ws_gui_app->v_new_value = + gtk_adjustment_get_value( + GTK_ADJUSTMENT( + ws_gui_app->ws_gui_vadj)) - ws_gui_app->v_delta; + if (ws_gui_app->v_new_value > + ws_gui_app->ws_gui_vadj->lower) + { + gtk_adjustment_set_value( + GTK_ADJUSTMENT(ws_gui_app->ws_gui_vadj), + ws_gui_app->v_new_value); + } + + break; + } + + case HILDON_HARDKEY_DOWN: + { + gtk_container_set_focus_vadjustment( + GTK_CONTAINER(ws_gui_app->ws_gui_scrolledwindow_left), + gtk_scrolled_window_get_vadjustment( + GTK_SCROLLED_WINDOW( + ws_gui_app->ws_gui_scrolledwindow_left))); + ws_gui_app->v_new_value = gtk_adjustment_get_value( + GTK_ADJUSTMENT(ws_gui_app->ws_gui_vadj)) + + ws_gui_app->v_delta; + + if (ws_gui_app->v_new_value < + (ws_gui_app->ws_gui_vadj->upper - + ws_gui_app->ws_gui_vadj->page_size)) + { + gtk_adjustment_set_value( + GTK_ADJUSTMENT(ws_gui_app->ws_gui_vadj), + ws_gui_app->v_new_value); + } + break; + } + + case HILDON_HARDKEY_LEFT: + { + gtk_container_set_focus_hadjustment( + GTK_CONTAINER(ws_gui_app->ws_gui_scrolledwindow_left), + gtk_scrolled_window_get_hadjustment( + GTK_SCROLLED_WINDOW( + ws_gui_app->ws_gui_scrolledwindow_left))); + + ws_gui_app->h_new_value = gtk_adjustment_get_value( + GTK_ADJUSTMENT(ws_gui_app->ws_gui_hadj)) + - ws_gui_app->h_delta; + + if (ws_gui_app->h_new_value > + ws_gui_app->ws_gui_hadj->lower) + { + gtk_adjustment_set_value( + GTK_ADJUSTMENT(ws_gui_app->ws_gui_hadj), + ws_gui_app->h_new_value); + } + } + break; + + case HILDON_HARDKEY_RIGHT: + { + gtk_container_set_focus_hadjustment( + GTK_CONTAINER(ws_gui_app->ws_gui_scrolledwindow_left), + gtk_scrolled_window_get_hadjustment( + GTK_SCROLLED_WINDOW( + ws_gui_app->ws_gui_scrolledwindow_left))); + + ws_gui_app->h_new_value = gtk_adjustment_get_value( + GTK_ADJUSTMENT(ws_gui_app->ws_gui_hadj)) + + ws_gui_app->h_delta; + + if (ws_gui_app->h_new_value < + (ws_gui_app->ws_gui_hadj->upper - + ws_gui_app->ws_gui_hadj->page_size)) + { + gtk_adjustment_set_value( + GTK_ADJUSTMENT(ws_gui_app->ws_gui_hadj), + ws_gui_app->h_new_value); + } + } + break; + + case HILDON_HARDKEY_SELECT: + ws_gui_search(NULL, ws_gui_app); + break; + + case HILDON_HARDKEY_FULLSCREEN: + ws_gui_full_screen(NULL, ws_gui_app); + break; + + case HILDON_HARDKEY_INCREASE: + ws_gui_html_zoom_in(NULL, ws_gui_app); + break; + + case HILDON_HARDKEY_DECREASE: + ws_gui_html_zoom_out(NULL, ws_gui_app); + break; + + case HILDON_HARDKEY_ESC: + ws_gui_search_stop(NULL, ws_gui_app); + break; + + default: + return FALSE; + break; + } + return TRUE; +} + +/** this function allow to hide words list using menu item from application menu + * + * @param checkmenuitem - the object which received the signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_words_list_hide_from_menu(GtkCheckMenuItem *checkmenuitem, + gpointer user_data) +{ + WSGuiApp* ws_gui_app = (WSGuiApp *)user_data; + if (gtk_check_menu_item_get_active( + GTK_CHECK_MENU_ITEM(ws_gui_app->ws_gui_menu->ws_gui_menu_hide_list))) + { + gtk_widget_hide(ws_gui_app->ws_gui_scrolledwindow_left); + gtk_toggle_tool_button_set_active( + GTK_TOGGLE_TOOL_BUTTON(ws_gui_app->ws_gui_toobar_button_hide), + TRUE); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM( + ws_gui_app->ws_gui_menu->ws_gui_menu_hide_list), + TRUE); + } + else + { + gtk_widget_show(ws_gui_app->ws_gui_scrolledwindow_left); + gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON( + ws_gui_app->ws_gui_toobar_button_hide), + FALSE); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM( + ws_gui_app->ws_gui_menu->ws_gui_menu_hide_list), + FALSE); + } +} + +/** this function allow to hide words list using toggle button placed in +the find toolbar + * + * @param toolbar - the object which received the signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_words_list_hide(GtkToggleButton *togglebutton, gpointer user_data) +{ + WSGuiApp* ws_gui_app = (WSGuiApp *)user_data; + + if (gtk_toggle_tool_button_get_active( + GTK_TOGGLE_TOOL_BUTTON(ws_gui_app->ws_gui_toobar_button_hide))) + { + gtk_widget_hide(ws_gui_app->ws_gui_scrolledwindow_left); + gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON( + ws_gui_app->ws_gui_toobar_button_hide), + TRUE); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM( + ws_gui_app->ws_gui_menu->ws_gui_menu_hide_list), + TRUE); + } + else + { + gtk_widget_show(ws_gui_app->ws_gui_scrolledwindow_left); + gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON( + ws_gui_app->ws_gui_toobar_button_hide), + FALSE); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM( + ws_gui_app->ws_gui_menu->ws_gui_menu_hide_list), + FALSE); + } +} + +/** add word to the history + * + * @param new_word - word which is going to be append to the history array + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_history_add(char *new_word, gpointer user_data) +{ + WSGuiApp* ws_gui_app = (WSGuiApp *)user_data; + + if (ws_gui_app->history_flag != TRUE) + { + + guint i; + gchar *tmp_word; + gchar *tmp_last_searched; + gchar *tmp_iter = NULL; + gchar *previous_word = " "; + + if (ws_gui_app->ws_gui_history_cur_pos > -1 && + g_array_index(ws_gui_app->ws_gui_history, + gchar*, + ws_gui_app->ws_gui_history_cur_pos) != NULL) + { + previous_word = NULL; + previous_word = g_array_index( + ws_gui_app->ws_gui_history, + gchar*, + ws_gui_app->ws_gui_history_cur_pos); + } + + i = ws_gui_app->ws_gui_history_cur_pos + 1; + gchar *tmp = g_array_index(ws_gui_app->ws_gui_history, + gchar*, + i); + //tmp_iter = gtk_tree_model_get_string_from_iter (GTK_TREE_MODEL(ws_gui_app->ws_gui_w_list->ws_gui_model), &ws_gui_app->ws_gui_w_list->ws_gui_iter); + + if (previous_word != NULL && + strcmp(previous_word, new_word) != 0) + { + while (tmp != NULL) + { + g_array_remove_index( + ws_gui_app->ws_gui_history_list, + i); + g_array_remove_index( + ws_gui_app->ws_gui_history_iter, + i); + + + g_array_remove_index( + ws_gui_app->ws_gui_history, + i); + + tmp = g_array_index( + ws_gui_app->ws_gui_history, + gchar*, + i); + } + + i = 0; + ws_gui_app->ws_gui_history_cur_pos ++; + + if (ws_gui_app->bookmark_mode == FALSE) + { + tmp_last_searched = g_strdup(ws_gui_app->last_searched); + } + else + { + tmp_last_searched = g_strdup(ws_gui_app->last_searched_in_book); + } + + g_array_append_val(ws_gui_app->ws_gui_history_list, + tmp_last_searched); + + tmp_word = g_strdup(new_word); + + g_array_append_val(ws_gui_app->ws_gui_history, tmp_word); + g_array_append_val(ws_gui_app->ws_gui_history_iter, tmp_iter); + + + if(ws_gui_app->ws_gui_history->len > HISTORY_LEN) + { + g_array_remove_index(ws_gui_app->ws_gui_history, 0); + g_array_remove_index(ws_gui_app->ws_gui_history_list, + 0); + g_array_remove_index(ws_gui_app->ws_gui_history_iter, + 0); + + ws_gui_app->ws_gui_history_cur_pos--; + } + + i = 0; + + tmp = g_array_index(ws_gui_app->ws_gui_history, gchar*, i); + } + + } + + ws_gui_check_history(ws_gui_app); +} + +/** display previously choosen word (previous from the history array) + if avaible, sets current position in the history array + * + * @param button - button which recived a signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_history_back(GtkButton *button, gpointer user_data) +{ + WSGuiApp* ws_gui_app = (WSGuiApp *)user_data; + + ws_gui_app->history_flag = TRUE; + + if (ws_gui_app->ws_gui_history_cur_pos > -1) + { + ws_gui_app->ws_gui_history_cur_pos = + ws_gui_app->ws_gui_history_cur_pos - 1; + + + g_object_set(G_OBJECT(ws_gui_app->ws_gui_hildon_find_toolbar), + "prefix", + (g_array_index(ws_gui_app->ws_gui_history_list, + gchar*, + ws_gui_app->ws_gui_history_cur_pos)), + NULL); + + ws_dbus_client_find_word (ws_gui_app->dbus_data, + g_strstrip(g_array_index(ws_gui_app->ws_gui_history_list, + gchar*, + ws_gui_app->ws_gui_history_cur_pos)) + ); + gtk_widget_hide(ws_gui_app->ws_gui_list_hbox); + //gtk_widget_show(ws_gui_app->ws_gui_banner_translation_loading); + ws_gui_app->loading = TRUE; + ws_gui_set_toolbar_avail(ws_gui_app); + } + else + { + ws_gui_app->loading = FALSE; + ws_gui_set_toolbar_avail(ws_gui_app); + } + + ws_gui_check_history(ws_gui_app); +} + +/** display choosen word, next in the history array (if avaible), +sets current position in the history array + * + * @param button - button which recived a signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_history_next(GtkButton *button, gpointer user_data) +{ + WSGuiApp* ws_gui_app = (WSGuiApp *)user_data; + + ws_gui_app->history_flag = TRUE; + + gchar *tmp = g_array_index(ws_gui_app->ws_gui_history, + gchar*, + ws_gui_app->ws_gui_history_cur_pos+1); + + if ((ws_gui_app->ws_gui_history_cur_pos < HISTORY_LEN-1) + && (tmp != NULL)) + { + ws_gui_app->ws_gui_history_cur_pos = + ws_gui_app->ws_gui_history_cur_pos + 1; + + + g_object_set(G_OBJECT(ws_gui_app->ws_gui_hildon_find_toolbar), + "prefix", + (g_array_index(ws_gui_app->ws_gui_history_list, + gchar*, + ws_gui_app->ws_gui_history_cur_pos)), + NULL); + + + ws_dbus_client_find_word(ws_gui_app->dbus_data, + g_strstrip(g_array_index(ws_gui_app->ws_gui_history_list, + gchar*, + ws_gui_app->ws_gui_history_cur_pos)) + ); + + gtk_widget_hide(ws_gui_app->ws_gui_list_hbox); + //gtk_widget_show(ws_gui_app->ws_gui_banner_translation_loading); + ws_gui_app->loading = TRUE; + ws_gui_set_toolbar_avail(ws_gui_app); + } + else + { + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_toobar_button_forward), + FALSE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_find_next), + FALSE); + } + + ws_gui_check_history(ws_gui_app); +} + +/** check current position in the history array and sets sensitivity of buttons +/ menu items, depends on availablity of words in the history + * + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_check_history(gpointer user_data) +{ + WSGuiApp* ws_gui_app = (WSGuiApp *)user_data; + + gchar *tmp = g_array_index(ws_gui_app->ws_gui_history, + gchar*, + ws_gui_app->ws_gui_history_cur_pos+1); + + if ((ws_gui_app->ws_gui_history_cur_pos+1 < HISTORY_LEN) + && (tmp != NULL)) + { + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_toobar_button_forward), + TRUE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_find_next), + TRUE); + } + else + { + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_toobar_button_forward), + FALSE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_find_next), + FALSE); + } + + tmp = g_array_index(ws_gui_app->ws_gui_history, + gchar*, + ws_gui_app->ws_gui_history_cur_pos-1); + if ((ws_gui_app->ws_gui_history_cur_pos > 0) && (tmp != NULL)) + { + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_toobar_button_back), + TRUE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_find_prev), + TRUE); + } + else + { + gtk_widget_set_sensitive ( + GTK_WIDGET(ws_gui_app->ws_gui_toobar_button_back), + FALSE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_find_prev), + FALSE); + } +} + +/** create TreeView Model, which allows to display words list + * + * @param words_list - array with words(found in a dictionary), recived from + * DBUS; + * @param user_data - user data set when the signal handler was connected + * @return + */ +GtkTreeModel * create_and_fill_model (GArray *words_list, gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + g_signal_handlers_block_by_func(G_OBJECT (ws_gui_app->ws_gui_w_list->ws_gui_view), + G_CALLBACK (ws_gui_view_cursor_changed), + ws_gui_app); + + guint i = 0; + gchar *tmp = g_strdup(g_array_index(words_list, gchar*, i)); + + if (tmp != NULL) + { + ws_gui_clear_list(ws_gui_app->ws_gui_w_list->ws_gui_store); + } + + gboolean valid; + valid = gtk_tree_model_get_iter_first( + GTK_TREE_MODEL(ws_gui_app->ws_gui_w_list->ws_gui_store), + &ws_gui_app->ws_gui_w_list->ws_gui_iter); + + /* Append a row and fill in some data */ + while (tmp != NULL) + { + gtk_list_store_append (ws_gui_app->ws_gui_w_list->ws_gui_store, + &ws_gui_app->ws_gui_w_list->ws_gui_iter); + + gtk_list_store_set (ws_gui_app->ws_gui_w_list->ws_gui_store, + &ws_gui_app->ws_gui_w_list->ws_gui_iter, + COL_WORD, tmp, + -1); + i=i+1; + g_free(tmp); + tmp = NULL; + tmp = g_strdup(g_array_index(words_list, gchar*, i)); + }; + + g_free(tmp); + tmp = NULL; + tmp = g_strdup(g_array_index(words_list, gchar*, 0)); + + + if (ws_gui_app->history_flag == FALSE && tmp != NULL) + { + //gtk_widget_show(ws_gui_app->ws_gui_banner_translation_loading); + ws_dbus_client_find_translation(ws_gui_app->dbus_data, tmp); + ws_gui_history_add(tmp, ws_gui_app); + + g_free(ws_gui_app->last_word); + ws_gui_app->last_word = NULL; + ws_gui_app->last_word = g_strdup (tmp); + ws_gui_app->history_flag = FALSE; + } + + g_signal_handlers_unblock_by_func(G_OBJECT( + ws_gui_app->ws_gui_w_list->ws_gui_view), + G_CALLBACK (ws_gui_view_cursor_changed), + ws_gui_app); + + g_free(tmp); + return GTK_TREE_MODEL(ws_gui_app->ws_gui_w_list->ws_gui_store); + +} + +/** create TreeView and TreeModel using create_and_fill_model() function; + it is necessary to display found words in a words list; + * + * @param words_list - array with words(found in a dictionary), + * recived from DBUS; + * @param user_data - user data set when the signal handler was connected + * @return + */ +GtkWidget * create_view_and_model (GArray *words_list, gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + ws_gui_app->ws_gui_w_list->ws_gui_view = gtk_tree_view_new (); + + ws_gui_app->ws_gui_w_list->ws_gui_renderer=gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes( + GTK_TREE_VIEW (ws_gui_app->ws_gui_w_list->ws_gui_view), + -1, + "Name", + ws_gui_app->ws_gui_w_list->ws_gui_renderer, + "text", + COL_WORD, + NULL); + ws_gui_app->ws_gui_w_list->ws_gui_model = + create_and_fill_model(words_list, ws_gui_app); + + gtk_tree_view_set_model( + GTK_TREE_VIEW (ws_gui_app->ws_gui_w_list->ws_gui_view), + ws_gui_app->ws_gui_w_list->ws_gui_model); + g_object_unref (ws_gui_app->ws_gui_w_list->ws_gui_model); + + return ws_gui_app->ws_gui_w_list->ws_gui_view; +} + +/** switch application between fun screen and normal mode + * + * @param menuitem - object which recived the signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_full_screen(GtkMenuItem *menuitem, gpointer user_data) +{ + + WSGuiApp* ws_gui_app = (WSGuiApp*)user_data; + if (ws_gui_app->ws_gui_full_screen_flag == FALSE) { + + gtk_window_fullscreen( + GTK_WINDOW(ws_gui_app->ws_gui_hildon_window)); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM( + ws_gui_app->ws_gui_menu->ws_gui_menu_full_screen), + TRUE); + ws_gui_app->ws_gui_full_screen_flag = TRUE; + gtk_infoprint(GTK_WINDOW(ws_gui_app->ws_gui_hildon_window), + _("ws_ib_fullscreen_on")); + } + else + { + gtk_window_unfullscreen( + GTK_WINDOW(ws_gui_app->ws_gui_hildon_window)); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM( + ws_gui_app->ws_gui_menu->ws_gui_menu_full_screen), + FALSE); + ws_gui_app->ws_gui_full_screen_flag = FALSE; + gtk_infoprint(GTK_WINDOW(ws_gui_app->ws_gui_hildon_window), + _("ws_ib_fullscreen_off")); + } +} + +/** search for selected text in a dictionary + * + * @param menuitem - object which recived the signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_popup_search(GtkMenuItem *menuitem, gpointer user_data) +{ + WSGuiApp* ws_gui_app = (WSGuiApp*)user_data; + gchar *temp; + ws_gui_app->ws_gui_clipboard_primary = + gtk_widget_get_clipboard(ws_gui_app->ws_gui_html, + GDK_SELECTION_PRIMARY); + temp = gtk_clipboard_wait_for_text( + ws_gui_app->ws_gui_clipboard_primary); + + g_strstrip(temp); + if (temp != NULL || strcmp(temp, " ")) + { + g_object_set(G_OBJECT(ws_gui_app->ws_gui_hildon_find_toolbar), + "prefix", + temp, + NULL); + ws_dbus_client_find_word (ws_gui_app->dbus_data, temp); + gtk_widget_hide(ws_gui_app->ws_gui_list_hbox); + } + else + { + hildon_banner_show_information( + GTK_WIDGET(ws_gui_app->ws_gui_hildon_window), + NULL, + _("ws_ni_no_text_selected")); + } +} + +/** select whole text in the translation (html) area + * + * @param menuitem - object which recived the signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_html_select_all(GtkMenuItem *menuitem, gpointer user_data) +{ + WSGuiApp* ws_gui_app = (WSGuiApp*)user_data; + gtk_html_select_all(GTK_HTML(ws_gui_app->ws_gui_html)); +} + +/** copy selected text to the clipoard from context popup menu + * + * @param menuitem - object which recived the signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_html_copy(GtkMenuItem *menuitem, gpointer user_data) +{ + WSGuiApp* ws_gui_app = (WSGuiApp*)user_data; + gtk_html_copy(GTK_HTML(ws_gui_app->ws_gui_html)); + gtk_infoprint(GTK_WINDOW(ws_gui_app->ws_gui_hildon_window), + _("ws_ib_copied")); +} + +/** paste copied text into toolbar entry + * + * @param menuitem - object which recived the signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_html_paste(GtkMenuItem *menuitem, gpointer user_data) +{ + WSGuiApp* ws_gui_app = (WSGuiApp*)user_data; + + gchar *temp; + gchar *temp2; + temp = gtk_clipboard_wait_for_text(ws_gui_app->ws_gui_clipboard); + g_object_get(G_OBJECT(ws_gui_app->ws_gui_hildon_find_toolbar), + "prefix", + &temp2, + NULL); + temp = g_strconcat(temp2, temp, NULL); + temp = g_strdelimit(temp, "\n", ' '); + g_object_set(G_OBJECT(ws_gui_app->ws_gui_hildon_find_toolbar), + "prefix", + temp, + NULL); + gtk_infoprint(GTK_WINDOW(ws_gui_app->ws_gui_hildon_window), + _("ws_ib_pasted")); +} + +/** zoom in text in translation (html) area + * + * @param menuitem - object which recived the signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_html_zoom_in(GtkMenuItem *menuitem, gpointer user_data) +{ + WSGuiApp* ws_gui_app = (WSGuiApp*)user_data; + ws_gui_app->zoom = ws_gui_app->zoom + ZOOM_STEP; + if (ws_gui_app->zoom > ZOOM_MAX) + { + ws_gui_app->zoom = ws_gui_app->zoom - ZOOM_STEP; + gtk_infoprint(GTK_WINDOW( + ws_gui_app->ws_gui_hildon_window), + _("ws_ib_max_zoom")); + } + else + { + gtk_html_set_magnification(GTK_HTML(ws_gui_app->ws_gui_html), + ws_gui_app->zoom); + + if ((WS_GUI_ABS(ws_gui_app->zoom - ZOOM_DEFAULT)) < 0.000001) + { + gtk_infoprint(GTK_WINDOW( + ws_gui_app->ws_gui_hildon_window), + _("ws_ib_zoom_default")); + } + else + { + gtk_infoprint(GTK_WINDOW( + ws_gui_app->ws_gui_hildon_window), + _("ws_ib_zoom_in")); + } + } +} + +/** zoom out text in translation (html) area + * + * @param menuitem - object which recived the signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_html_zoom_out(GtkMenuItem *menuitem, gpointer user_data) +{ + WSGuiApp* ws_gui_app = (WSGuiApp*)user_data; + ws_gui_app->zoom = ws_gui_app->zoom - ZOOM_STEP; + if (ws_gui_app->zoom < ZOOM_MIN) + { + ws_gui_app->zoom = ws_gui_app->zoom + ZOOM_STEP; + gtk_infoprint(GTK_WINDOW( + ws_gui_app->ws_gui_hildon_window), + _("ws_ib_min_zoom")); + } + else + { + gtk_html_set_magnification(GTK_HTML(ws_gui_app->ws_gui_html), + ws_gui_app->zoom); + + if ((WS_GUI_ABS(ws_gui_app->zoom - ZOOM_DEFAULT)) < 0.000001) + { + gtk_infoprint(GTK_WINDOW( + ws_gui_app->ws_gui_hildon_window), + _("ws_ib_zoom_default")); + } + else + { + gtk_infoprint(GTK_WINDOW( + ws_gui_app->ws_gui_hildon_window), + _("ws_ib_zoom_out")); + } + } +} + +/** start searching, send typed word to DBUS and query for words + * + * @param widget - object which recived the signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_search(GtkWidget * widget, gpointer user_data) +{ + WSGuiApp* ws_gui_app = (WSGuiApp*)user_data; + + ws_gui_app->stop_clicked = FALSE; + + // if (ws_gui_app->ws_gui_banner_flag == FALSE) + //{ + gchar* ws_gui_text = NULL; + g_object_get(G_OBJECT(ws_gui_app->ws_gui_hildon_find_toolbar), + "prefix", + &ws_gui_text, + NULL); + + if (ws_gui_app->bookmark_mode == FALSE) + { + g_free(ws_gui_app->last_searched); + ws_gui_app->last_searched = NULL; + ws_gui_app->last_searched = g_strdup(ws_gui_text); + } + else + { + g_free(ws_gui_app->last_searched_in_book); + ws_gui_app->last_searched_in_book = NULL; + ws_gui_app->last_searched_in_book = g_strdup(ws_gui_text); + } + + g_strstrip(ws_gui_text); + if (strlen(ws_gui_text) != 0) + { + //gtk_widget_show(ws_gui_app->ws_gui_banner_list_searching); + + ws_gui_app->loading = TRUE; + ws_gui_set_toolbar_avail(ws_gui_app); + + // ws_gui_app->ws_gui_banner_flag = TRUE; + //ws_gui_fill_html(" ", ws_gui_app); + //ws_gui_app->html_flag = FALSE; + ws_dbus_client_find_word (ws_gui_app->dbus_data, ws_gui_text); + gtk_widget_hide(GTK_WIDGET(ws_gui_app->ws_gui_list_hbox)); + g_free(ws_gui_text); + } + else + { + gtk_infoprint( + GTK_WINDOW(ws_gui_app->ws_gui_hildon_window), + _("ws_ni_no_word_typed")); + } + g_free(ws_gui_app->last_word); + ws_gui_app->last_word=NULL; + //} +} + +/** stop search process + * + * @param button - object which recived the signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_search_stop(GtkButton *button, gpointer user_data) +{ + WSGuiApp* ws_gui_app = (WSGuiApp *)user_data; + ws_gui_app->stop_clicked = TRUE; + // if (ws_gui_app->ws_gui_banner_flag == TRUE || ws_gui_app->loading == TRUE) + if (ws_gui_app->loading == TRUE) + { + //gtk_widget_hide(GTK_WIDGET(ws_gui_app->ws_gui_banner_list_searching)); + + ws_gui_app->loading = FALSE; + ws_gui_set_toolbar_avail(ws_gui_app); + + //ws_gui_app->ws_gui_banner_flag = FALSE; + + ws_dbus_notify(ws_gui_app->dbus_data, WS_DBUS_INFO_STOP_SEARCH); + gtk_infoprint(GTK_WINDOW(ws_gui_app->ws_gui_hildon_window), + _("ws_ni_search_aborted")); + } +} + +/** this function is called just before closing application; +it sends signal to DBUS and destroys it; + * + * @param widget - object which recived the signal + * @param event - + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_on_exit (GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + WSGuiApp* ws_gui_app = (WSGuiApp *)user_data; + ws_gui_app->bookmark_mode = FALSE; + ws_gui_set_bookmarks_sensitivity(ws_gui_app); + g_timer_destroy(ws_gui_app->timer); + ws_dbus_notify(ws_gui_app->dbus_data, WS_DBUS_INFO_TERMINATE); + ws_dbus_destroy (ws_gui_app->dbus_data); + ws_gui_free_memory(ws_gui_app); + gtk_main_quit(); + exit (0); +} + +/** this function is called just before closing application, +from application menu; it sends signal to DBUS and destroys it; + * + * @param menuitem - object which recived the signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_menu_quit(GtkMenuItem *menuitem, gpointer user_data) +{ + WSGuiApp* ws_gui_app = (WSGuiApp *)user_data; + ws_gui_app->bookmark_mode = FALSE; + ws_gui_set_bookmarks_sensitivity(ws_gui_app); + g_timer_destroy(ws_gui_app->timer); + ws_dbus_notify(ws_gui_app->dbus_data, WS_DBUS_INFO_TERMINATE); + ws_dbus_destroy (ws_gui_app->dbus_data); + ws_gui_free_memory(ws_gui_app); + gtk_main_quit(); + exit (0); +} + +/** fill translation area with text (html) recived from DBUS + * + * @param html_context - text which is going to be displayed; it should be html + * @param user_data - user data set when the function was called + * @return + */ +void ws_gui_fill_html(char *html_context, gpointer user_data) +{ + WSGuiApp* ws_gui_app = (WSGuiApp*)user_data; + gtk_html_set_editable (GTK_HTML(ws_gui_app->ws_gui_html), FALSE); + + gtk_html_load_from_string(GTK_HTML(ws_gui_app->ws_gui_html), + html_context, + -1); +} + +/** read adjustment of left scrollwindow, which is necessary to navigate with +arrow keys inside words list + * + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_read_adjustment(gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + ws_gui_app->ws_gui_hadj = + gtk_scrolled_window_get_hadjustment( + GTK_SCROLLED_WINDOW( + ws_gui_app->ws_gui_scrolledwindow_left)); + + ws_gui_app->h_delta = (ws_gui_app->ws_gui_hadj->upper - + ws_gui_app->ws_gui_hadj->lower)/SCROLL_STEP_H; + + ws_gui_app->ws_gui_vadj = gtk_scrolled_window_get_vadjustment( + GTK_SCROLLED_WINDOW(ws_gui_app->ws_gui_scrolledwindow_left)); + + ws_gui_app->v_delta = (ws_gui_app->ws_gui_vadj->upper - + ws_gui_app->ws_gui_vadj->lower)/SCROLL_STEP_V; + ws_gui_app->v_new_value = + gtk_adjustment_get_value(GTK_ADJUSTMENT(ws_gui_app->ws_gui_vadj)) + + ws_gui_app->v_delta; + + gtk_container_set_focus_vadjustment( + GTK_CONTAINER(ws_gui_app->ws_gui_scrolledwindow_left), + gtk_scrolled_window_get_vadjustment( + GTK_SCROLLED_WINDOW(ws_gui_app->ws_gui_scrolledwindow_left))); + +} + +/** allows to display image in html area + * + * @param html - object which received a signal + * @param url - url to the image + * @param stream - html stream + * @return + */ +void ws_gui_url_requested ( + GtkHTML *html, + const char *url, + GtkHTMLStream *stream) +{ + int fd; + + if (url && !strncmp (url, "file:", 5)) { + url += 5; + fd = open (url, O_RDONLY); + if (fd != -1) { + gchar *buf; + size_t size; + buf = alloca (8192); + while ((size = read (fd, buf, 8192)) > 0) { + gtk_html_stream_write (stream, buf, size); + } + gtk_html_stream_close(stream, size == -1 + ? GTK_HTML_STREAM_ERROR + : GTK_HTML_STREAM_OK); + close (fd); + + return; + } + } + + gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR); +} + +/** handles button press event and examines what kind of event was it + suppose to be + * + * @param widget - object which received a signal + * @param event - type of event which has been performed + * @param user_data - user data set when the signal handler was connected + * @return TRUE to stop other handlers from being invoked for the event. + FALSE to propagate the event further + */ +gboolean ws_gui_button_press(GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + if (ws_gui_app->ws_gui_sel_flag == FALSE) + { + if (event->type == GDK_2BUTTON_PRESS) + { + ws_gui_app->ws_gui_double_click = TRUE; + g_timer_stop(ws_gui_app->timer); + g_timer_reset(ws_gui_app->timer); + return FALSE; + } + + g_signal_stop_emission_by_name(G_OBJECT( + ws_gui_app->ws_gui_html), + "button-press-event"); + g_timer_start(ws_gui_app->timer); + gtk_timeout_add((guint)(PRESS_TIME*1000), + (GtkFunction)(ws_gui_show_popup), + ws_gui_app); + return FALSE; + } + else + { + ws_gui_app->ws_gui_sel_flag = FALSE; + return FALSE; + } + +} + +/** handles button release event and examines whether 'click' or 'tap and hold' +event it supposed to be + * + * @param widget - object which received a signal + * @param event - type of event which has been performed + * @param user_data - user data set when the signal handler was connected + * @return TRUE to stop other handlers from being invoked for the event. + FALSE to propagate the event further + */ +gboolean ws_gui_button_release (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + gdouble tmp = g_timer_elapsed(ws_gui_app->timer, NULL); + g_timer_stop(ws_gui_app->timer); + g_timer_reset(ws_gui_app->timer); + if (ws_gui_app->ws_gui_double_click == TRUE) + { + ws_gui_app->ws_gui_double_click = FALSE; + return FALSE; + } + else if (tmp < PRESS_TIME) + { + struct _GtkHTML *tmp = (struct _GtkHTML *) + (ws_gui_app->ws_gui_html); + html_engine_unselect_all(tmp->engine); + return TRUE; + } + return FALSE; +} + +/** displays popup menu if user holds a stylus more than PRESS_TIME seconds + * + * @param user_data - user data set when the signal handler was connected + * @return + */ +guint ws_gui_show_popup (gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + gdouble tmp = g_timer_elapsed(ws_gui_app->timer, NULL); + if (tmp > PRESS_TIME) + { + ws_gui_create_popup_menu(ws_gui_app); + } + return (guint)(FALSE); + +} + +/** checks clipboard content and sets sensitivity of widgets + * + * @param widget - object which recived a signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_check_clipboard (GtkWidget *widget, gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + if (gtk_clipboard_wait_for_text(ws_gui_app->ws_gui_clipboard) != NULL) + { + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_paste), + TRUE); + } + else + { + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_paste), + FALSE); + } + + struct _GtkHTML *tmp = (struct _GtkHTML *)(ws_gui_app->ws_gui_html); + + if (html_engine_is_selection_active(tmp->engine) == TRUE) + { + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_menu_copy), + TRUE); + } + else + { + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_menu_copy), + FALSE); + } + + if (ws_gui_app->html_flag == FALSE) + { + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_menu_select_all), + FALSE); + } + else + { + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_menu_select_all), + TRUE); + } + +} + +/** gets received string (with translation), formats it and sends it to be + * displayed + * + * @param received_string - content received from Manager + * @param user_data - user data set when the function has been called + * @return + */ +gchar * format_html (gchar * received_string, gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + GString *str_final; + GString *str_tmp; + str_final = g_string_new(received_string); + str_tmp = g_string_new(received_string); + gchar * tmp; + gchar * tmp2; + gchar * returned_value; + + ws_gui_app->raw_translation=g_string_erase(ws_gui_app->raw_translation, + 0, + -1); + + while (strstr(str_final->str, "") != NULL) + { + tmp = strstr(str_final->str, ""); + str_final = g_string_erase(str_final, + (long)(tmp - str_final->str), + 14); + str_final = g_string_insert(str_final, + (long)(tmp - str_final->str), + "
" + "
" + "
" + ""); + + tmp2 = strstr(str_tmp->str, ""); + if (ws_gui_app->last_word != NULL) + { + str_tmp = g_string_erase(str_tmp, + (long)(tmp2 - str_tmp->str), + 14 + strlen(ws_gui_app->last_word)); + } + } + + while (strstr(str_final->str, "") != NULL) + { + tmp = strstr(str_final->str, ""); + str_final = g_string_erase(str_final, + (long)(tmp - str_final->str), + 16); + str_final = g_string_insert(str_final, + (long)(tmp - str_final->str), + "
"); + + tmp2 = strstr(str_tmp->str, ""); + str_tmp = g_string_erase(str_tmp, + (long)(tmp2 - str_tmp->str), + 16); + } + + while (strstr(str_final->str, "") != NULL) + { + tmp = strstr(str_final->str, ""); + str_final = g_string_erase (str_final, + (long)(tmp - str_final->str), + 18); + str_final = g_string_insert (str_final, + (long)(tmp - str_final->str), + "
"); + + tmp2 = strstr(str_tmp->str, ""); + str_tmp = g_string_erase(str_tmp, + (long)(tmp2 - str_tmp->str), + 18); + } + + while (strstr(str_final->str, "") != NULL) + { + tmp = strstr(str_final->str, ""); + str_final = g_string_erase(str_final, + (long)(tmp - str_final->str), + 20); + str_final = g_string_insert(str_final, + (long)(tmp - str_final->str), + "
"); + + tmp2 = strstr(str_tmp->str, ""); + str_tmp = g_string_erase(str_tmp, + (long)(tmp2 - str_tmp->str), + 20); + } + + str_final = g_string_append(str_final, + "
"); + + ws_gui_app->raw_translation = g_string_insert( + ws_gui_app->raw_translation, + 0, + str_tmp->str); + + returned_value = g_strdup(str_final->str); + g_string_free(str_final, TRUE); + g_string_free(str_tmp, TRUE); + return returned_value; +} + +/** open bookmarks database + * + * @param menuitem - object which recived the signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_dictionary_open_bookmark(GtkMenuItem *menuitem, gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + ws_gui_read_active_dictionaries(ws_gui_app); + + /*list has to be cleared if we're gonna use a completely different dict*/ + ws_gui_clear_list(ws_gui_app->ws_gui_w_list->ws_gui_store); + g_free(ws_gui_app->last_word); + ws_gui_app->last_word = NULL; + + ws_gui_app->bookmark_mode = TRUE; + ws_gui_set_bookmarks_sensitivity(ws_gui_app); + g_object_set(G_OBJECT(ws_gui_app->ws_gui_hildon_find_toolbar), + "prefix", + "*", + NULL); + ws_dbus_notify(ws_gui_app->dbus_data, WS_DBUS_BOOKMARK_MODE_ON); + + if(ws_gui_app->ws_gui_history->len >= 0) + { + ws_gui_clear_array(ws_gui_app->ws_gui_history); + ws_gui_clear_array(ws_gui_app->ws_gui_history_list); + ws_gui_clear_array(ws_gui_app->ws_gui_history_iter); + ws_gui_app->ws_gui_history_cur_pos = -1; + } + ws_gui_check_history(ws_gui_app); + + ws_gui_fill_html(" ", ws_gui_app); + ws_gui_app->html_flag = FALSE; + ws_dbus_client_find_word(ws_gui_app->dbus_data, "*"); + gtk_widget_hide(ws_gui_app->ws_gui_list_hbox); + ws_gui_search(NULL, ws_gui_app); + +} + +/** closes bookmarks database + * + * @param menuitem - object which recived the signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_dictionary_close_bookmark(GtkMenuItem *menuitem, gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + ws_gui_read_active_dictionaries(ws_gui_app); + + g_free(ws_gui_app->last_word); + ws_gui_app->last_word = NULL; + + ws_gui_app->bookmark_mode = FALSE; + ws_gui_set_bookmarks_sensitivity(ws_gui_app); + ws_dbus_notify(ws_gui_app->dbus_data, WS_DBUS_BOOKMARK_MODE_OFF); + + if(ws_gui_app->ws_gui_history->len >= 0) + { + ws_gui_clear_array(ws_gui_app->ws_gui_history); + ws_gui_clear_array(ws_gui_app->ws_gui_history_list); + ws_gui_clear_array(ws_gui_app->ws_gui_history_iter); + ws_gui_app->ws_gui_history_cur_pos = -1; + } + ws_gui_check_history(ws_gui_app); + + ws_gui_fill_html(" ", ws_gui_app); + ws_gui_app->html_flag = FALSE; + g_strstrip(ws_gui_app->last_searched); + if (ws_gui_app->last_searched != NULL) + { + g_object_set(G_OBJECT(ws_gui_app->ws_gui_hildon_find_toolbar), + "prefix", + ws_gui_app->last_searched, + NULL); + //ws_dbus_client_find_word(ws_gui_app->dbus_data, ws_gui_app->last_searched); + ws_gui_search(NULL, ws_gui_app); + } + else + { + g_object_set(G_OBJECT(ws_gui_app->ws_gui_hildon_find_toolbar), + "prefix", + "\0", + NULL); + GArray *tmp; + tmp = g_array_new(TRUE, TRUE, sizeof(gchar*)); + gtk_list_store_clear(ws_gui_app->ws_gui_w_list->ws_gui_store); + ws_gui_app->ws_gui_w_list->ws_gui_model = + create_and_fill_model(tmp, ws_gui_app); + + ws_dbus_client_find_word(ws_gui_app->dbus_data, ws_gui_app->last_searched); + gtk_widget_hide(ws_gui_app->ws_gui_list_hbox); + ws_gui_search(NULL, ws_gui_app); + } +} + +/** adds bookmark to bookmarks database + * + * @param menuitem - object which recived the signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_dictionary_add_bookmark(GtkMenuItem *menuitem, gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + if (ws_gui_app->last_word != NULL) + { + ws_gui_add_bookmark_dialog(ws_gui_app); + } + else + { + gtk_infoprint( + GTK_WINDOW(ws_gui_app->ws_gui_hildon_window), + _("ws_ni_select_word_to_add")); + } +} + +/** removes bookmark from bookmarks database + * + * @param menuitem - object which recived the signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_dictionary_remove_bookmark(GtkMenuItem *menuitem, + gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + if (ws_gui_app->last_word != NULL) + { + ws_gui_remove_bookmark_dialog(ws_gui_app); + + gchar *temp; + g_object_get(G_OBJECT(ws_gui_app->ws_gui_hildon_find_toolbar), + "prefix", + &temp, + NULL); + ws_dbus_client_find_word (ws_gui_app->dbus_data, temp); + gtk_widget_hide(ws_gui_app->ws_gui_list_hbox); + + } + else + { + gtk_infoprint( + GTK_WINDOW(ws_gui_app->ws_gui_hildon_window), + _("ws_ni_select_word_to_remove")); + } + + +} + +/** checks wheather dictionaries are available or not; according to the result + * dimmes proper menuitem + * + * @param menuitem - object which recived the signal + * @param user_data - user data set when the signal handler was connected + * @return + */ +void ws_gui_dict_availablity(GtkMenuItem *menuitem, gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + if (gconf_client_dir_exists(ws_gui_app->client, + GCONF_PATH, NULL) == TRUE) + { + ws_gui_app->directories = gconf_client_all_dirs( + ws_gui_app->client, + GCONF_PATH, + NULL + ); + + + if(g_slist_length(ws_gui_app->directories) != 0) + { + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_menu_remove_dict), + TRUE); + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_menu_select_dict), + TRUE); + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_menu_optimize_dict), + TRUE); + } + + } + else + { + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_menu_remove_dict), + FALSE); + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_menu_select_dict), + FALSE); + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_menu_optimize_dict), + FALSE); + } + +} + +/** sets sensitivity of menu items due to bookmark's mode + * + * @param user_data - user data set when the function was called + * @return + */ +void ws_gui_set_bookmarks_sensitivity(gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + int i; + gchar *string; + gchar *name; + + if (ws_gui_app->bookmark_mode == TRUE) + { + g_slist_free(ws_gui_app->directories_last); + ws_gui_app->directories_last = NULL; + ws_gui_app->directories_last = g_slist_alloc(); + g_slist_free(ws_gui_app->directories); + ws_gui_app->directories = g_slist_alloc(); + + ws_gui_app->directories = gconf_client_all_dirs( + ws_gui_app->client, + GCONF_PATH, NULL); + + for (i=0; idirectories); i++) + { + string = (gchar*)g_slist_nth_data(ws_gui_app->directories, i); + name = g_path_get_basename(string); + string = g_strconcat(string, "/active", NULL); + + if (gconf_client_get_bool(ws_gui_app->client, string, NULL) == TRUE) + { + ws_gui_app->directories_last = + g_slist_append(ws_gui_app->directories_last, + string); + } + + if (strcmp(name, "bookmarks") == 0) + { + gconf_client_set_bool(ws_gui_app->client, + string, + TRUE, + NULL); + } + else + { + gconf_client_set_bool(ws_gui_app->client, + string, + FALSE, + NULL); + } + } + + //setting sensitivity of components + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_open_bookmark), + FALSE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_close_bookmark), + TRUE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_remove_bookmark), + TRUE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_add_bookmark), + FALSE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_dictionaries), + FALSE); + } + else + { + gchar *bookmarks_path = g_strconcat(GCONF_PATH, "/bookmarks/active", NULL); + if (g_slist_length(ws_gui_app->directories_last) > 0) + { + gconf_client_set_bool(ws_gui_app->client, bookmarks_path, FALSE, NULL); + } + + for (i=0; idirectories_last); i++) + { + string = (gchar*)g_slist_nth_data(ws_gui_app->directories_last, + i); + + if (string != NULL) + { + gconf_client_set_bool(ws_gui_app->client, + string, + TRUE, + NULL); + } + } + + //setting sensitivity of components + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_open_bookmark), + TRUE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_close_bookmark), + FALSE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_remove_bookmark), + FALSE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_add_bookmark), + TRUE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_dictionaries), + TRUE); + + g_free(bookmarks_path); + } + +} + +/** sets sensitivity of menu items due to user selection made + * + * @param user_data - user data set when the function was called + * @return + */ +void ws_gui_set_bookmark_menu_items(GtkMenuItem *menuitem, gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + if (ws_gui_app->bookmark_mode == TRUE && ws_gui_app->last_word != NULL) + { + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_remove_bookmark), + TRUE); + } + else + { + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_remove_bookmark), + FALSE); + } + + if (ws_gui_app->last_word == NULL || + (ws_gui_app->last_word[0] == '\0') || + ws_gui_app->bookmark_mode == TRUE) + { + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_add_bookmark), + FALSE); + } + else + { + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_add_bookmark), + TRUE); + } +} +/** reads gconf entries and sets variables with a proper data; it is necessary + * for changing the bookmarks mode + * + * @param user_data - user data set when the function was called + * @return + */ +void ws_gui_read_active_dictionaries(gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + + ws_gui_app->directories = gconf_client_all_dirs(ws_gui_app->client, + GCONF_PATH, + NULL); +} + +void ws_gui_clear_array(GArray *history) +{ + if(history->len >= 0) + { + history = g_array_remove_range(history, 0, history->len); + } +} + +void ws_gui_view_cursor_changed(GtkTreeView *treeview, gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + gchar *string; + if (gtk_tree_selection_get_selected(ws_gui_app->ws_gui_w_list->ws_gui_selection, + &ws_gui_app->ws_gui_w_list->ws_gui_model, + &ws_gui_app->ws_gui_w_list->ws_gui_iter)) + { + gtk_tree_model_get(ws_gui_app->ws_gui_w_list->ws_gui_model, + &ws_gui_app->ws_gui_w_list->ws_gui_iter, + COL_WORD, + &string, + -1); + if (string != NULL) + { + //gtk_widget_show(ws_gui_app->ws_gui_banner_translation_loading); + ws_gui_app->loading = TRUE; + ws_gui_set_toolbar_avail(ws_gui_app); + + ws_dbus_client_find_translation(ws_gui_app->dbus_data, string); + + + g_free(ws_gui_app->last_word); + ws_gui_app->last_word = NULL; + ws_gui_app->last_word = g_strdup (string); + + if (ws_gui_app->history_flag == FALSE) + { + ws_gui_history_add(string, ws_gui_app); + + } + g_free (string); + } + + } + + +} + +void ws_gui_set_toolbar_avail(gpointer user_data) { + + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + if (ws_gui_app->loading == TRUE) + { + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_toobar_button_stop), + TRUE); + + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_search), + FALSE); + + } + else + { + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_toobar_button_stop), + FALSE); + + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_menu->ws_gui_menu_search), + TRUE); + } +} diff --git a/src/gui/src/ws_gui_layout.c b/src/gui/src/ws_gui_layout.c new file mode 100644 index 0000000..54e29ce --- /dev/null +++ b/src/gui/src/ws_gui_layout.c @@ -0,0 +1,1789 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#include +#include +#include +#include +#include + + +/** this function creates main window and it components; moreover there are + * signal connections; + * + * @param user_data - data set when the signal handler was connected + */ +void ws_gui_create_window(gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + ws_gui_app->welcome_note = g_strconcat("

", + _("ws_ni_welcome"), "
", + NULL); + +// ws_gui_app->ws_gui_w_list->ws_gui_list_item_data_string = +// (ws_gui_app->welcome_note); + + GArray *array_tmp = g_array_new (TRUE, TRUE, sizeof(gchar*)); + ws_gui_app->raw_translation = g_string_new(" "); + ws_gui_app->last_searched = NULL; + ws_gui_app->last_searched_in_book = NULL; + ws_gui_app->last_word = NULL; + + ws_gui_app->ws_gui_banner_flag = FALSE; + ws_gui_app->ws_gui_full_screen_flag = FALSE; + ws_gui_app->caching_flag = FALSE; + ws_gui_app->ws_gui_double_click = FALSE; + ws_gui_app->ws_gui_sel_flag = FALSE; + ws_gui_app->bookmark_mode = FALSE; + ws_gui_app->bookmark_avail = TRUE; + ws_gui_app->html_flag = TRUE; + ws_gui_app->loading = FALSE; + ws_gui_app->stop_clicked = FALSE; + + ws_gui_app->zoom = ZOOM_DEFAULT; + + ws_gui_app->timer = g_timer_new(); + g_timer_stop(ws_gui_app->timer); + + ws_gui_app->ws_gui_history = g_array_new(TRUE, TRUE, sizeof(gchar*)); + ws_gui_app->ws_gui_history_list = g_array_new(TRUE, TRUE, sizeof(gchar*)); + ws_gui_app->ws_gui_history_iter = g_array_new(TRUE, TRUE, sizeof(gchar*)); + ws_gui_app->history_flag = FALSE; + ws_gui_app->ws_gui_history_cur_pos = -1; + + ws_gui_app->ws_gui_hildon_program = + HILDON_PROGRAM(hildon_program_get_instance()); + + g_set_application_name("WhiteStork"); + + ws_gui_app->ws_gui_hildon_window = HILDON_WINDOW(hildon_window_new()); + + hildon_program_add_window(ws_gui_app->ws_gui_hildon_program, + ws_gui_app->ws_gui_hildon_window); + + ws_gui_create_main_menu(ws_gui_app); + ws_gui_create_find_toolbar(ws_gui_app); + + ws_gui_app->ws_gui_hpane = gtk_hpaned_new(); + + ws_gui_app->ws_gui_scrolledwindow_left = + gtk_scrolled_window_new (NULL, NULL); + + gtk_scrolled_window_set_policy( + GTK_SCROLLED_WINDOW (ws_gui_app->ws_gui_scrolledwindow_left), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + + gtk_paned_set_position(GTK_PANED(ws_gui_app->ws_gui_hpane), 100); + + gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW + (ws_gui_app->ws_gui_scrolledwindow_left), + GTK_CORNER_TOP_LEFT); + + ws_gui_app->ws_gui_scrolledwindow_right = + gtk_scrolled_window_new (NULL, NULL); + + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW + (ws_gui_app->ws_gui_scrolledwindow_right), + GTK_POLICY_NEVER, + GTK_POLICY_AUTOMATIC); + + ws_gui_app->ws_gui_w_list->ws_gui_store = + gtk_list_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_UINT); + + ws_gui_app->ws_gui_w_list->ws_gui_view = + create_view_and_model(array_tmp, ws_gui_app); + + g_array_free(array_tmp, TRUE); + + gtk_widget_show_all(GTK_WIDGET(ws_gui_app->ws_gui_w_list->ws_gui_view)); + + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW + (ws_gui_app->ws_gui_scrolledwindow_left), + ws_gui_app->ws_gui_w_list->ws_gui_view); + + ws_gui_app->ws_gui_html = gtk_html_new(); + + ws_gui_app->p = pango_font_description_from_string("Tahoma 12"); + gtk_widget_modify_font(GTK_WIDGET( + ws_gui_app->ws_gui_html),ws_gui_app->p); + + g_signal_connect(GTK_OBJECT (ws_gui_app->ws_gui_html), + "url_requested", + G_CALLBACK(ws_gui_url_requested), + ws_gui_app); + + gtk_html_load_from_string(GTK_HTML(ws_gui_app->ws_gui_html), + ws_gui_app->welcome_note, + -1); + + g_free(ws_gui_app->welcome_note); + ws_gui_app->welcome_note = NULL; + + gtk_html_set_magnification(GTK_HTML(ws_gui_app->ws_gui_html), + ws_gui_app->zoom); + + gtk_html_set_editable(GTK_HTML(ws_gui_app->ws_gui_html), FALSE); + gtk_html_allow_selection(GTK_HTML(ws_gui_app->ws_gui_html), TRUE); + + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW + (ws_gui_app->ws_gui_scrolledwindow_right), + ws_gui_app->ws_gui_html); + + /*adding vbox & label - used for notifications */ + + ws_gui_app->ws_gui_list_image = gtk_image_new_from_file("/usr/share/pixmaps/ws_warning_icon.png"); + ws_gui_app->ws_gui_list_eventbox = gtk_event_box_new (); + ws_gui_app->ws_gui_list_vbox = gtk_vbox_new(FALSE, 0); + ws_gui_app->ws_gui_list_hbox = gtk_hbox_new(FALSE, 5); + ws_gui_app->ws_gui_list_label = gtk_label_new(_("ws_ti_list_full")); + + ws_gui_app->p = pango_font_description_from_string("Tahoma 10"); + gtk_widget_modify_font(GTK_WIDGET(ws_gui_app->ws_gui_list_label), ws_gui_app->p); + + /*HBox packing ....*/ + gtk_box_pack_start(GTK_BOX(ws_gui_app->ws_gui_list_hbox), + ws_gui_app->ws_gui_list_image, + FALSE, + FALSE, + 0); + + gtk_box_pack_start(GTK_BOX(ws_gui_app->ws_gui_list_hbox), + ws_gui_app->ws_gui_list_label, + FALSE, + FALSE, + 0); + + // gtk_widget_set_size_request (ws_gui_app->ws_gui_list_label, 150, -1); + + /*VBox packing ....*/ + gtk_box_pack_start(GTK_BOX(ws_gui_app->ws_gui_list_vbox), + ws_gui_app->ws_gui_scrolledwindow_left, + TRUE, + TRUE, + 0); + + gtk_box_pack_start(GTK_BOX(ws_gui_app->ws_gui_list_vbox), + ws_gui_app->ws_gui_list_eventbox, + FALSE, + FALSE, + 0); + + gtk_container_add (GTK_CONTAINER (ws_gui_app->ws_gui_list_eventbox), + ws_gui_app->ws_gui_list_hbox); + /************************************************/ + + + gtk_paned_pack1(GTK_PANED(ws_gui_app->ws_gui_hpane), + ws_gui_app->ws_gui_list_vbox, + TRUE, + TRUE); + gtk_paned_pack2(GTK_PANED(ws_gui_app->ws_gui_hpane), + ws_gui_app->ws_gui_scrolledwindow_right, + TRUE, + TRUE); + + gtk_container_add(GTK_CONTAINER(ws_gui_app->ws_gui_hildon_window), + ws_gui_app->ws_gui_hpane); + + gtk_widget_show_all(GTK_WIDGET(ws_gui_app->ws_gui_hildon_window)); + + gtk_widget_hide(GTK_WIDGET(ws_gui_app->ws_gui_list_hbox)); + + ws_gui_app->ws_gui_w_list->ws_gui_selection = + gtk_tree_view_get_selection (GTK_TREE_VIEW + (ws_gui_app->ws_gui_w_list->ws_gui_view)); + + gtk_tree_selection_set_mode( + ws_gui_app->ws_gui_w_list->ws_gui_selection, + GTK_SELECTION_BROWSE); + + ws_gui_app->directories = g_slist_alloc(); + ws_gui_set_bookmarks_sensitivity(ws_gui_app); + + ws_gui_app->ws_gui_banner_list_searching = hildon_banner_show_animation( + GTK_WIDGET(ws_gui_app->ws_gui_hildon_window), + NULL, + _("ws_ab_searching")); + + ws_gui_app->ws_gui_banner_translation_loading = hildon_banner_show_animation( + GTK_WIDGET(ws_gui_app->ws_gui_hildon_window), + NULL, + _("ws_ab_loading")); + + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_popup_bookmark), + FALSE); + + gtk_widget_hide(GTK_WIDGET(ws_gui_app->ws_gui_banner_list_searching)); + gtk_widget_hide(GTK_WIDGET(ws_gui_app->ws_gui_banner_translation_loading)); +} + +/** this function creates a find toolbar and connects signals to the tollbars + * components + * + * @param user_data - set when the signal handler was connected + */ +void ws_gui_create_find_toolbar(gpointer user_data) +{ + WSGuiApp* ws_gui_app = (WSGuiApp*)user_data; + + GtkToolItem *space; + ws_gui_app->ws_gui_hildon_find_toolbar = + HILDON_FIND_TOOLBAR(hildon_find_toolbar_new(_("ws_me_search_find"))); + + ws_gui_app->ws_gui_toobar_button_hide = + gtk_toggle_tool_button_new_from_stock(GTK_STOCK_GOTO_FIRST); + ws_gui_app->ws_gui_toobar_button_back = + gtk_tool_button_new_from_stock(GTK_STOCK_GO_BACK); + ws_gui_app->ws_gui_toobar_button_forward = + gtk_tool_button_new_from_stock(GTK_STOCK_GO_FORWARD); + ws_gui_app->ws_gui_toobar_button_stop = + gtk_tool_button_new_from_stock(GTK_STOCK_STOP); + space = gtk_separator_tool_item_new(); + + ws_gui_app->ws_gui_toobar_button_close = + gtk_toolbar_get_nth_item(GTK_TOOLBAR( + ws_gui_app->ws_gui_hildon_find_toolbar), + 4); + + ws_gui_app->ws_gui_toobar_button_start = gtk_toolbar_get_nth_item(GTK_TOOLBAR( + ws_gui_app->ws_gui_hildon_find_toolbar), + 2); + + gtk_tool_item_set_visible_horizontal( + ws_gui_app->ws_gui_toobar_button_close, + FALSE); + + gtk_toolbar_insert(GTK_TOOLBAR(ws_gui_app->ws_gui_hildon_find_toolbar), + ws_gui_app->ws_gui_toobar_button_hide, + 0); + gtk_toolbar_insert(GTK_TOOLBAR(ws_gui_app->ws_gui_hildon_find_toolbar), + ws_gui_app->ws_gui_toobar_button_back, + -1); + gtk_toolbar_insert(GTK_TOOLBAR(ws_gui_app->ws_gui_hildon_find_toolbar), + ws_gui_app->ws_gui_toobar_button_forward, + -1); + gtk_toolbar_insert(GTK_TOOLBAR(ws_gui_app->ws_gui_hildon_find_toolbar), + space, + -1); + gtk_toolbar_insert(GTK_TOOLBAR(ws_gui_app->ws_gui_hildon_find_toolbar), + ws_gui_app->ws_gui_toobar_button_stop, + -1); + + g_signal_connect(G_OBJECT(ws_gui_app->ws_gui_hildon_find_toolbar), + "search", + G_CALLBACK(ws_gui_search), + ws_gui_app); + + g_signal_connect(G_OBJECT(ws_gui_app->ws_gui_toobar_button_hide), + "toggled", + G_CALLBACK(ws_gui_words_list_hide), + ws_gui_app); + + g_signal_connect(G_OBJECT(ws_gui_app->ws_gui_toobar_button_back), + "clicked", + G_CALLBACK(ws_gui_history_back), + ws_gui_app); + + g_signal_connect(G_OBJECT(ws_gui_app->ws_gui_toobar_button_forward), + "clicked", + G_CALLBACK(ws_gui_history_next), + ws_gui_app); + g_signal_connect(G_OBJECT(ws_gui_app->ws_gui_toobar_button_stop), + "clicked", + G_CALLBACK(ws_gui_search_stop), + ws_gui_app); + + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_toobar_button_back), + FALSE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_toobar_button_forward), + FALSE); + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_toobar_button_stop), + FALSE); + + hildon_find_toolbar_highlight_entry((HildonFindToolbar*)(ws_gui_app->ws_gui_hildon_find_toolbar), + FALSE); + //gtk_toolbar_set_tooltips(GTK_TOOLBAR(ws_gui_app->ws_gui_hildon_find_toolbar), TRUE); + + hildon_window_add_toolbar(ws_gui_app->ws_gui_hildon_window, + GTK_TOOLBAR(ws_gui_app->ws_gui_hildon_find_toolbar)); +} + +/** this function creates application menu and its items and connect signals to + * them + * + * @param user_data - set when the signal handler was connected + */ +void ws_gui_create_main_menu (gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + ws_gui_app->ws_gui_menu->ws_gui_submenu_0 = gtk_menu_new(); + ws_gui_app->ws_gui_menu->ws_gui_submenu_1 = gtk_menu_new(); + ws_gui_app->ws_gui_menu->ws_gui_submenu_2 = gtk_menu_new(); + ws_gui_app->ws_gui_menu->ws_gui_submenu_3 = gtk_menu_new(); + ws_gui_app->ws_gui_menu->ws_gui_submenu_4 = gtk_menu_new(); + ws_gui_app->ws_gui_menu->ws_gui_main_menu = gtk_menu_new(); + + ws_gui_app->ws_gui_menu->ws_gui_menu_dictionaries = + gtk_menu_item_new_with_label(_("ws_me_dictionaries")); + ws_gui_app->ws_gui_menu->ws_gui_menu_bookmarks = + gtk_menu_item_new_with_label(_("ws_me_bookmarks")); + ws_gui_app->ws_gui_menu->ws_gui_menu_edit = + gtk_menu_item_new_with_label(_("ws_me_edit")); + ws_gui_app->ws_gui_menu->ws_gui_menu_view = + gtk_menu_item_new_with_label(_("ws_me_view")); + ws_gui_app->ws_gui_menu->ws_gui_menu_search = + gtk_menu_item_new_with_label(_("ws_me_search")); + ws_gui_app->ws_gui_menu->ws_gui_menu_about = + gtk_menu_item_new_with_label(_("ws_me_about")); + ws_gui_app->ws_gui_menu->ws_gui_menu_close = + gtk_menu_item_new_with_label(_("ws_me_close")); + ws_gui_app->ws_gui_menu->ws_gui_separator = + gtk_separator_menu_item_new(); + ws_gui_app->ws_gui_menu->ws_gui_separator1 = + gtk_separator_menu_item_new(); + + ws_gui_app->ws_gui_menu->ws_gui_menu_load_dict = + gtk_menu_item_new_with_label(_("ws_me_dictionaries_load")); + ws_gui_app->ws_gui_menu->ws_gui_menu_select_dict = + gtk_menu_item_new_with_label(_("ws_me_dictionaries_select")); + ws_gui_app->ws_gui_menu->ws_gui_menu_remove_dict = + gtk_menu_item_new_with_label(_("ws_me_dictionaries_remove")); + ws_gui_app->ws_gui_menu->ws_gui_menu_optimize_dict = + gtk_menu_item_new_with_label(_("ws_me_dictionaries_optimize")); + + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_0, + ws_gui_app->ws_gui_menu->ws_gui_menu_load_dict); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_0, + ws_gui_app->ws_gui_menu->ws_gui_menu_select_dict); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_0, + ws_gui_app->ws_gui_menu->ws_gui_menu_remove_dict); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_0, + ws_gui_app->ws_gui_menu->ws_gui_menu_optimize_dict); + + ws_gui_app->ws_gui_menu->ws_gui_menu_open_bookmark = + gtk_menu_item_new_with_label(_("ws_me_bookmarks_open")); + ws_gui_app->ws_gui_menu->ws_gui_menu_close_bookmark = + gtk_menu_item_new_with_label(_("ws_me_bookmarks_close")); + ws_gui_app->ws_gui_menu->ws_gui_menu_add_bookmark = + gtk_menu_item_new_with_label(_("ws_me_bookmarks_add")); + ws_gui_app->ws_gui_menu->ws_gui_menu_remove_bookmark = + gtk_menu_item_new_with_label(_("ws_me_bookmarks_remove")); + + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_4, + ws_gui_app->ws_gui_menu->ws_gui_menu_open_bookmark); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_4, + ws_gui_app->ws_gui_menu->ws_gui_menu_close_bookmark); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_4, + ws_gui_app->ws_gui_menu->ws_gui_menu_add_bookmark); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_4, + ws_gui_app->ws_gui_menu->ws_gui_menu_remove_bookmark); + + ws_gui_app->ws_gui_menu->ws_gui_menu_copy = + gtk_menu_item_new_with_label(_("ws_me_edit_copy")); + ws_gui_app->ws_gui_menu->ws_gui_menu_paste = + gtk_menu_item_new_with_label(_("ws_me_edit_paste")); + ws_gui_app->ws_gui_menu->ws_gui_menu_select_all = + gtk_menu_item_new_with_label(_("ws_me_edit_select_all")); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_1, + ws_gui_app->ws_gui_menu->ws_gui_menu_copy); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_1, + ws_gui_app->ws_gui_menu->ws_gui_menu_paste); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_1, + ws_gui_app->ws_gui_menu->ws_gui_menu_select_all); + + ws_gui_app->ws_gui_menu->ws_gui_menu_hide_list = + gtk_check_menu_item_new_with_label(_("ws_me_view_hide_words_list")); + ws_gui_app->ws_gui_menu->ws_gui_menu_zoom_in = + gtk_menu_item_new_with_label(_("ws_me_view_zoom_in")); + ws_gui_app->ws_gui_menu->ws_gui_menu_zoom_out = + gtk_menu_item_new_with_label(_("ws_me_view_zoom_out")); + ws_gui_app->ws_gui_menu->ws_gui_menu_full_screen = + gtk_check_menu_item_new_with_label(_("ws_me_view_fullscreen")); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_2, + ws_gui_app->ws_gui_menu->ws_gui_menu_hide_list); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_2, + ws_gui_app->ws_gui_menu->ws_gui_menu_zoom_in); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_2, + ws_gui_app->ws_gui_menu->ws_gui_menu_zoom_out); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_2, + ws_gui_app->ws_gui_menu->ws_gui_menu_full_screen); + + ws_gui_app->ws_gui_menu->ws_gui_menu_find_word = + gtk_menu_item_new_with_label(_("ws_me_search_find")); + ws_gui_app->ws_gui_menu->ws_gui_menu_find_next = + gtk_menu_item_new_with_label(_("ws_me_search_find_next")); + ws_gui_app->ws_gui_menu->ws_gui_menu_find_prev = + gtk_menu_item_new_with_label(_("ws_me_search_find_prev")); + ws_gui_app->ws_gui_menu->ws_gui_menu_stop = + gtk_menu_item_new_with_label(_("ws_me_search_stop")); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_3, + ws_gui_app->ws_gui_menu->ws_gui_menu_find_word); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_3, + ws_gui_app->ws_gui_menu->ws_gui_menu_find_next); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_3, + ws_gui_app->ws_gui_menu->ws_gui_menu_find_prev); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_submenu_3, + ws_gui_app->ws_gui_menu->ws_gui_menu_stop); + + + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_main_menu, + ws_gui_app->ws_gui_menu->ws_gui_menu_dictionaries); + gtk_menu_item_set_submenu(GTK_MENU_ITEM + (ws_gui_app->ws_gui_menu->ws_gui_menu_dictionaries), + ws_gui_app->ws_gui_menu->ws_gui_submenu_0); + + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_main_menu, + ws_gui_app->ws_gui_menu->ws_gui_menu_bookmarks); + gtk_menu_item_set_submenu(GTK_MENU_ITEM + (ws_gui_app->ws_gui_menu->ws_gui_menu_bookmarks), + ws_gui_app->ws_gui_menu->ws_gui_submenu_4); + + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_main_menu, + ws_gui_app->ws_gui_menu->ws_gui_separator1); + + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_main_menu, + ws_gui_app->ws_gui_menu->ws_gui_menu_edit); + gtk_menu_item_set_submenu(GTK_MENU_ITEM + (ws_gui_app->ws_gui_menu->ws_gui_menu_edit), + ws_gui_app->ws_gui_menu->ws_gui_submenu_1); + + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_main_menu, + ws_gui_app->ws_gui_menu->ws_gui_menu_view); + gtk_menu_item_set_submenu(GTK_MENU_ITEM + (ws_gui_app->ws_gui_menu->ws_gui_menu_view), + ws_gui_app->ws_gui_menu->ws_gui_submenu_2); + + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_main_menu, + ws_gui_app->ws_gui_menu->ws_gui_menu_search); + gtk_menu_item_set_submenu(GTK_MENU_ITEM + (ws_gui_app->ws_gui_menu->ws_gui_menu_search), + ws_gui_app->ws_gui_menu->ws_gui_submenu_3); + + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_main_menu, + ws_gui_app->ws_gui_menu->ws_gui_separator); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_main_menu, + ws_gui_app->ws_gui_menu->ws_gui_menu_about); + gtk_menu_append(ws_gui_app->ws_gui_menu->ws_gui_main_menu, + ws_gui_app->ws_gui_menu->ws_gui_menu_close); + + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_load_dict), + "activate", + G_CALLBACK(ws_gui_dictionary_loader), + ws_gui_app); + g_signal_connect(G_OBJECT( + ws_gui_app->ws_gui_menu->ws_gui_menu_select_dict), + "activate", + G_CALLBACK(ws_gui_dictionary_chooser), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_remove_dict), + "activate", + G_CALLBACK(ws_gui_dictionary_remover), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_optimize_dict), + "activate", + G_CALLBACK(ws_gui_dictionary_optimizer), ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_open_bookmark), + "activate", + G_CALLBACK(ws_gui_dictionary_open_bookmark), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_close_bookmark), + "activate", + G_CALLBACK(ws_gui_dictionary_close_bookmark), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_add_bookmark), + "activate", + G_CALLBACK(ws_gui_dictionary_add_bookmark), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_remove_bookmark), + "activate", + G_CALLBACK(ws_gui_dictionary_remove_bookmark), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_copy), + "activate", + GTK_SIGNAL_FUNC(ws_gui_html_copy), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_paste), + "activate", + GTK_SIGNAL_FUNC(ws_gui_html_paste), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_select_all), + "activate", + GTK_SIGNAL_FUNC(ws_gui_html_select_all), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_hide_list), + "activate", + GTK_SIGNAL_FUNC(ws_gui_words_list_hide_from_menu), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_zoom_in), + "activate", + G_CALLBACK(ws_gui_html_zoom_in), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_zoom_out), + "activate", + G_CALLBACK(ws_gui_html_zoom_out), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_full_screen), + "activate", + GTK_SIGNAL_FUNC(ws_gui_full_screen), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_find_word), + "activate", + GTK_SIGNAL_FUNC(ws_gui_search), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_find_next), + "activate", + GTK_SIGNAL_FUNC(ws_gui_history_next), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_find_prev), + "activate", + GTK_SIGNAL_FUNC(ws_gui_history_back), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_stop), + "activate", + GTK_SIGNAL_FUNC(ws_gui_search_stop), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_about), + "activate", + G_CALLBACK(ws_gui_about_application), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_close), + "activate", + G_CALLBACK(ws_gui_menu_quit), + ws_gui_app); + + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_edit), + "activate", + GTK_SIGNAL_FUNC(ws_gui_check_clipboard), + ws_gui_app); + + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_dictionaries), + "activate", + GTK_SIGNAL_FUNC(ws_gui_dict_availablity), + ws_gui_app); + + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_menu_bookmarks), + "activate", + GTK_SIGNAL_FUNC(ws_gui_set_bookmark_menu_items), + ws_gui_app); + + hildon_window_set_menu(HILDON_WINDOW(ws_gui_app->ws_gui_hildon_window), + GTK_MENU( + ws_gui_app->ws_gui_menu->ws_gui_main_menu)); + + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_menu_stop), + FALSE); + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_menu_find_next), + FALSE); + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_menu_find_prev), + FALSE); + + + + gtk_widget_show_all(ws_gui_app->ws_gui_menu->ws_gui_main_menu); +} + + +/** this function creates contex popup menu and its items and connect signals to + * them + * + * @param user_data - set when the signal handler was connected + */ +void ws_gui_create_popup_menu (gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + ws_gui_app->ws_gui_menu->ws_gui_popup_menu = gtk_menu_new(); + ws_gui_app->ws_gui_menu->ws_gui_popup_submenu = gtk_menu_new(); + ws_gui_app->ws_gui_menu->ws_gui_separator = + gtk_separator_menu_item_new(); + + ws_gui_app->ws_gui_menu->ws_gui_popup_search = + gtk_menu_item_new_with_label(_("ws_mp_search")); + gtk_menu_append((ws_gui_app->ws_gui_menu->ws_gui_popup_menu), + ws_gui_app->ws_gui_menu->ws_gui_popup_search); + gtk_menu_append ((ws_gui_app->ws_gui_menu->ws_gui_popup_menu), + gtk_separator_menu_item_new()); + ws_gui_app->ws_gui_menu->ws_gui_popup_bookmark = + gtk_menu_item_new_with_label(_("ws_mp_add_bookmark")); + gtk_menu_append ((ws_gui_app->ws_gui_menu->ws_gui_popup_menu), + ws_gui_app->ws_gui_menu->ws_gui_popup_bookmark); + + ws_gui_app->ws_gui_menu->ws_gui_popup_copy = + gtk_menu_item_new_with_label(_("ws_mp_edit_copy")); + gtk_menu_append((ws_gui_app->ws_gui_menu->ws_gui_popup_submenu), + ws_gui_app->ws_gui_menu->ws_gui_popup_copy); + + ws_gui_app->ws_gui_menu->ws_gui_popup_paste = + gtk_menu_item_new_with_label(_("ws_mp_edit_paste")); + gtk_menu_append((ws_gui_app->ws_gui_menu->ws_gui_popup_submenu), + ws_gui_app->ws_gui_menu->ws_gui_popup_paste); + + ws_gui_app->ws_gui_menu->ws_gui_popup_select_all = + gtk_menu_item_new_with_label(_("ws_mp_edit_select_all")); + gtk_menu_append((ws_gui_app->ws_gui_menu->ws_gui_popup_submenu), + ws_gui_app->ws_gui_menu->ws_gui_popup_select_all); + + gtk_widget_show_all(ws_gui_app->ws_gui_menu->ws_gui_popup_submenu); + + ws_gui_app->ws_gui_menu->ws_gui_popup_edit = + gtk_menu_item_new_with_label (_("ws_mp_edit")); + gtk_menu_append ((ws_gui_app->ws_gui_menu->ws_gui_popup_menu), + ws_gui_app->ws_gui_menu->ws_gui_popup_edit); + + gtk_menu_append ((ws_gui_app->ws_gui_menu->ws_gui_popup_menu), + ws_gui_app->ws_gui_menu->ws_gui_separator); + + ws_gui_app->ws_gui_menu->ws_gui_popup_zoom_in = + gtk_menu_item_new_with_label (_("ws_mp_zoom_in")); + gtk_menu_append ((ws_gui_app->ws_gui_menu->ws_gui_popup_menu), + ws_gui_app->ws_gui_menu->ws_gui_popup_zoom_in); + + ws_gui_app->ws_gui_menu->ws_gui_popup_zoom_out = + gtk_menu_item_new_with_label (_("ws_mp_zoom_out")); + gtk_menu_append ((ws_gui_app->ws_gui_menu->ws_gui_popup_menu), + ws_gui_app->ws_gui_menu->ws_gui_popup_zoom_out); + + gtk_menu_item_set_submenu(GTK_MENU_ITEM + (ws_gui_app->ws_gui_menu->ws_gui_popup_edit), + ws_gui_app->ws_gui_menu->ws_gui_popup_submenu); + + struct _GtkHTML *tmp = (struct _GtkHTML *)(ws_gui_app->ws_gui_html); + + if (html_engine_is_selection_active(tmp->engine) == TRUE) + { + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_popup_search), + TRUE); + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_popup_copy), + TRUE); + } + else + { + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_popup_search), + FALSE); + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_popup_copy), + FALSE); + } + + if (ws_gui_app->html_flag == FALSE) + { + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_popup_select_all), + FALSE); + } + else + { + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_popup_select_all), + TRUE); + } + + gtk_widget_show_all(ws_gui_app->ws_gui_menu->ws_gui_popup_menu); + + + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_popup_search), + "activate", + G_CALLBACK(ws_gui_popup_search), + ws_gui_app); + + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_popup_bookmark), + "activate", + G_CALLBACK(ws_gui_dictionary_add_bookmark), + ws_gui_app); + + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_popup_copy), + "activate", + G_CALLBACK(ws_gui_html_copy), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_popup_paste), + "activate", + G_CALLBACK(ws_gui_html_paste), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_popup_select_all), + "activate", + G_CALLBACK(ws_gui_html_select_all), + ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_popup_zoom_in), + "activate", + G_CALLBACK(ws_gui_html_zoom_in), ws_gui_app); + g_signal_connect(G_OBJECT + (ws_gui_app->ws_gui_menu->ws_gui_popup_zoom_out), + "activate", + G_CALLBACK(ws_gui_html_zoom_out), + ws_gui_app); + + if (gtk_clipboard_wait_for_text(ws_gui_app->ws_gui_clipboard) != NULL) + { + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_popup_paste), + TRUE); + } + else + { + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_popup_paste), + FALSE); + } + + + if (ws_gui_app->bookmark_avail == FALSE) + { + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_popup_bookmark), + FALSE); + } + + else + { + if (ws_gui_app->bookmark_mode == TRUE) + { + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_popup_bookmark), + FALSE); + } + else + { + g_strstrip(ws_gui_app->last_word); + //g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "\n\nlast_word: %s\n\n", ws_gui_app->last_word); + + if (ws_gui_app->last_word == NULL || + (ws_gui_app->last_word[0] == '\0')) + { + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_popup_bookmark), + FALSE); + } + else + { + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_menu->ws_gui_popup_bookmark), + TRUE); + } + } + } + gtk_menu_popup(GTK_MENU(ws_gui_app->ws_gui_menu->ws_gui_popup_menu), + NULL, + NULL, + NULL, + ws_gui_app, + 0, + 0); +} + +/** this function creates dialog popup window and allows to select dictionaries + * which user wants to use + * + * @param menuitem - the object which received the signal + * @param user_data - set when the signal handler was connected + */ +void ws_gui_dictionary_chooser(GtkMenuItem *menuitem, gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + GtkWidget *dialog1; + GtkWidget *dialog_vbox1; + GtkWidget *scrolledwindow1; + GtkWidget *viewport1; + GtkWidget *vbox1; + + GtkWidget *checkbutton; + GtkWidget *cancel_button; + GtkWidget *ok_button; + guint i =0; + gchar* string; + gchar* path; + const gchar* name; + GArray *checkboxes; + + checkboxes = g_array_new (TRUE, TRUE, sizeof(GtkWidget*)); + + if (gconf_client_dir_exists(ws_gui_app->client, + GCONF_PATH, NULL) == TRUE) + { + ws_gui_app->directories = + gconf_client_all_dirs(ws_gui_app->client, + GCONF_PATH, + NULL); + } + else + { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, + "\n.::GUI::. /apps/WhiteStork/Dictionaries does not exist!!"); + } + + dialog1 = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (dialog1), + (_("ws_ti_choose_dictionaries_title"))); + gtk_window_set_type_hint (GTK_WINDOW (dialog1), + GDK_WINDOW_TYPE_HINT_DIALOG); + gtk_window_set_default_size(GTK_WINDOW (dialog1), 300, 200); + + dialog_vbox1 = GTK_DIALOG (dialog1)->vbox; + gtk_widget_show (dialog_vbox1); + + scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow1); + gtk_box_pack_start (GTK_BOX (dialog_vbox1), + scrolledwindow1, + TRUE, + TRUE, + 0); + + viewport1 = gtk_viewport_new (NULL, NULL); + gtk_widget_show (viewport1); + gtk_container_add (GTK_CONTAINER (scrolledwindow1), viewport1); + + vbox1 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox1); + gtk_container_add (GTK_CONTAINER (viewport1), vbox1); + + for (i=0; i< g_slist_length(ws_gui_app->directories);i++) + { + string = (gchar*)g_slist_nth_data(ws_gui_app->directories, i); + name = g_path_get_basename(string); + checkbutton = gtk_check_button_new_with_label(name); + path = g_strconcat(string, "/active", NULL); + + if (gconf_client_get_bool(ws_gui_app->client, + path, + NULL) == TRUE) + { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( + checkbutton), + TRUE); + } + else + { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( + checkbutton), + FALSE); + } + + g_array_append_val(checkboxes, checkbutton); + gtk_box_pack_start (GTK_BOX (vbox1), + checkbutton, + FALSE, + FALSE, + 0); + + if (strcmp(name, "bookmarks") == 0) + { + if (ws_gui_app->bookmark_avail == FALSE) + { + gtk_widget_set_sensitive(GTK_WIDGET(checkbutton), + FALSE); + } + } + + gtk_widget_show (checkbutton); + } + + cancel_button = gtk_button_new_from_stock (_("ws_db_cancel")); + gtk_widget_show (cancel_button); + gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), + cancel_button, + GTK_RESPONSE_CANCEL); + + ok_button = gtk_button_new_from_stock (_("ws_db_ok")); + gtk_widget_show (ok_button); + gtk_dialog_add_action_widget(GTK_DIALOG (dialog1), + ok_button, + GTK_RESPONSE_OK); + + i = gtk_dialog_run(GTK_DIALOG(dialog1)); + + if (i == GTK_RESPONSE_OK) + { + for(i=0;i<(checkboxes->len);i++) + { + if (gtk_toggle_button_get_active( + GTK_TOGGLE_BUTTON(g_array_index(checkboxes, + GtkWidget *, i))) == TRUE) + { + name = gtk_button_get_label(GTK_BUTTON( + g_array_index(checkboxes, GtkWidget *, i))); + + path=g_strconcat(GCONF_PATH, + "/", + name, + "/active", + NULL); + gconf_client_set_bool(ws_gui_app->client, + path, + TRUE, + NULL); + } + + if (gtk_toggle_button_get_active( + GTK_TOGGLE_BUTTON(g_array_index(checkboxes, + GtkWidget *, i))) == FALSE) + { + name = gtk_button_get_label(GTK_BUTTON( + g_array_index(checkboxes, GtkWidget *, i))); + + path=g_strconcat(GCONF_PATH, + "/", + name, + "/active", + NULL); + gconf_client_set_bool(ws_gui_app->client, + path, + FALSE, + NULL); + } + } + + ws_dbus_notify(ws_gui_app->dbus_data, + WS_DBUS_INFO_CONFIG_CHANGED); + + if(ws_gui_app->ws_gui_history->len >= 0) + { + ws_gui_clear_array(ws_gui_app->ws_gui_history); + ws_gui_clear_array(ws_gui_app->ws_gui_history_list); + ws_gui_clear_array(ws_gui_app->ws_gui_history_iter); + ws_gui_app->ws_gui_history_cur_pos = -1; + } + ws_gui_check_history(ws_gui_app); + + gtk_widget_destroy (dialog1); + } + else if (i == GTK_RESPONSE_CANCEL) + { + gtk_widget_destroy (dialog1); + } + + g_slist_free(ws_gui_app->directories); +} + +/** this function creates dialog popup window and allows optimize dictionaries + * + * @param menuitem - the object which received the signal + * @param user_data - set when the signal handler was connected + */ +void ws_gui_dictionary_optimizer(GtkMenuItem *menuitem, gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + GtkWidget *dialog1; + GtkWidget *dialog_vbox1; + GtkWidget *scrolledwindow1; + GtkWidget *viewport1; + GtkWidget *vbox1; + + GtkWidget *checkbutton; + GtkWidget *cancel_button; + GtkWidget *ok_button; + guint i =0; + gchar* string; + gchar* path; + const gchar* name; + GArray *checkboxes; + + checkboxes = g_array_new (TRUE, TRUE, sizeof(GtkWidget*)); + + if (gconf_client_dir_exists(ws_gui_app->client, + GCONF_PATH, + NULL) == TRUE) + { + ws_gui_app->directories = + gconf_client_all_dirs(ws_gui_app->client, GCONF_PATH, NULL); + } + else + { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, + "\n.::GUI::. /apps/WhiteStork/Dictionaries does not exist!!"); + } + + for (i=0; i< g_slist_length(ws_gui_app->directories);i++) + { + string = (gchar*)g_slist_nth_data(ws_gui_app->directories, i); + name = g_path_get_basename(string); + + path = g_strconcat(string, "/optimized", NULL); + if (gconf_client_get_bool (ws_gui_app->client, + path, + NULL) == FALSE) + { + checkbutton = gtk_check_button_new_with_label(name); + g_array_append_val(checkboxes, checkbutton); + } + } + if (checkboxes->len <= 0) + { + ws_gui_app->ws_message_dialog = gtk_message_dialog_new( + GTK_WINDOW(ws_gui_app->ws_gui_hildon_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("ws_ni_no_dictionaries_to_optimize")); + gtk_widget_show_all(ws_gui_app->ws_message_dialog); + if (gtk_dialog_run (GTK_DIALOG ( + ws_gui_app->ws_message_dialog)) == GTK_RESPONSE_OK) + { + gtk_widget_destroy(ws_gui_app->ws_message_dialog); + } + } + else + { + dialog1 = gtk_dialog_new (); + gtk_window_set_title(GTK_WINDOW (dialog1), + (_("ws_ti_choose_dictionaries_title"))); + gtk_window_set_type_hint(GTK_WINDOW (dialog1), + GDK_WINDOW_TYPE_HINT_DIALOG); + gtk_window_set_default_size(GTK_WINDOW (dialog1), 300, 200); + + dialog_vbox1 = GTK_DIALOG (dialog1)->vbox; + gtk_widget_show (dialog_vbox1); + + scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow1); + gtk_box_pack_start(GTK_BOX (dialog_vbox1), + scrolledwindow1, + TRUE, + TRUE, + 0); + + viewport1 = gtk_viewport_new (NULL, NULL); + gtk_widget_show (viewport1); + gtk_container_add (GTK_CONTAINER (scrolledwindow1), viewport1); + + vbox1 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox1); + gtk_container_add (GTK_CONTAINER (viewport1), vbox1); + for (i=0; ilen; i++) + { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( + g_array_index(checkboxes, GtkWidget*, i)), + FALSE); + gtk_box_pack_start(GTK_BOX (vbox1), + g_array_index(checkboxes, GtkWidget*, i), + FALSE, + FALSE, + 0); + gtk_widget_show(g_array_index(checkboxes, + GtkWidget*, + i)); + } + cancel_button = gtk_button_new_from_stock (_("ws_db_cancel")); + gtk_widget_show (cancel_button); + gtk_dialog_add_action_widget(GTK_DIALOG (dialog1), + cancel_button, + GTK_RESPONSE_CANCEL); + ok_button = gtk_button_new_from_stock (_("ws_db_ok")); + gtk_widget_show (ok_button); + gtk_dialog_add_action_widget(GTK_DIALOG (dialog1), + ok_button, + GTK_RESPONSE_OK); + i = gtk_dialog_run(GTK_DIALOG(dialog1)); + if (i == GTK_RESPONSE_OK) + { + for(i=0;i<(checkboxes->len);i++) + { + if (gtk_toggle_button_get_active( + GTK_TOGGLE_BUTTON( + g_array_index(checkboxes, + GtkWidget *, i))) == TRUE) + { + name = gtk_button_get_label(GTK_BUTTON( + g_array_index(checkboxes, + GtkWidget *, + i))); + path=g_strconcat(GCONF_PATH, + "/", + name, + "/optimized", + NULL); + gconf_client_set_bool( + ws_gui_app->client, + path, + TRUE, + NULL); + } + if (gtk_toggle_button_get_active( + GTK_TOGGLE_BUTTON( + g_array_index(checkboxes, + GtkWidget *, i))) == FALSE) + { + name = gtk_button_get_label(GTK_BUTTON + (g_array_index(checkboxes, + GtkWidget*, + i))); + path=g_strconcat(GCONF_PATH, + "/", + name, + "/optimized", + NULL); + gconf_client_set_bool( + ws_gui_app->client, + path, + FALSE, + NULL); + } + } + ws_dbus_notify(ws_gui_app->dbus_data, + WS_DBUS_INFO_CONFIG_CHANGED); + gtk_widget_destroy (dialog1); + } + else if (i == GTK_RESPONSE_CANCEL) + { + gtk_widget_destroy (dialog1); + } + } + g_slist_free(ws_gui_app->directories); +} + +/** this function creates dialog popup window which allows to load a new + *dictionary file into application + * + * @param menuitem - the object which received the signal + * @param user_data - set when the signal handler was connected + */ +void ws_gui_dictionary_loader(GtkMenuItem *menuitem, gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + GtkWidget *dialog; + // GtkWidget *dialog2; + + dialog = hildon_file_chooser_dialog_new( + GTK_WINDOW(ws_gui_app->ws_gui_hildon_window), + GTK_FILE_CHOOSER_ACTION_OPEN); + + gtk_window_set_default_size(GTK_WINDOW (dialog), 200, 200); + gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER(dialog), FALSE); + + //gtk_widget_show(GTK_WIDGET(dialog)); + + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) + { + gchar *filename; + gchar *name; + // gchar *path; + gint len; + // gchar *filepath; + + gchar* tmp; + + filename = gtk_file_chooser_get_filename( + GTK_FILE_CHOOSER (dialog)); + name = g_path_get_basename(filename); + len = strlen(filename) - strlen(name) -1; + tmp = g_strndup (filename, len); + + + tmp = g_path_get_basename(tmp); + + if (g_str_has_suffix(name, ".xdxf") + || g_str_has_suffix(name, ".idx") + || g_str_has_suffix(name, ".ifo") + || g_str_has_suffix(name, ".idx.gz") + || g_str_has_suffix(name, ".dict") + || g_str_has_suffix(name, ".dict.dz")) + { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "\n:::GUUUUIII GUIII::: check"); + if (ws_gui_load_dict(filename, ws_gui_app) == TRUE) + { + gtk_widget_destroy(dialog); + gtk_infoprint(GTK_WINDOW( + ws_gui_app->ws_gui_hildon_window), + _("ws_ni_dictionary_added")); + } + } + else if (g_str_has_suffix(name, ".bz2")) + { + gtk_widget_destroy(dialog); + ws_dbus_client_extract_dictionary(ws_gui_app->dbus_data, filename); + } + else + { + gtk_widget_destroy (dialog); + gtk_infoprint(GTK_WINDOW( + ws_gui_app->ws_gui_hildon_window), + _("ws_ni_dictionary_wrong_file")); + } + + } + else + { + gtk_widget_destroy (dialog); + } + +} + +/** this function creates dialog popup window which allows to load dictionary + * + * @param filename - the object which received the signal + * @param user_data - set when the signal handler was connected + */ +gboolean ws_gui_load_dict(gchar *filename, gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + GtkWidget *dialog1; + GtkWidget *dialog2; + gchar *name = g_path_get_basename(filename); + gchar *path; + gint len; + gchar *filepath; + + len = strlen(filename) - strlen(name) -1; + gchar *tmp = g_strndup (filename, len);; + tmp = g_path_get_basename(tmp); + + + filepath = g_strndup (filename, len); + path = g_strconcat(GCONF_PATH, "/", tmp, "/path", NULL); + gconf_client_set_string(ws_gui_app->client, + path, + filepath, + NULL); + g_free(path); + path = NULL; + path = g_strconcat(GCONF_PATH, + "/", + tmp, + "/active", + NULL); + + dialog1 = gtk_message_dialog_new(GTK_WINDOW( + ws_gui_app->ws_gui_hildon_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + _("ws_ni_dictionaries_activation_question")); + + gtk_widget_show_all(GTK_WIDGET(dialog1)); + + if (gtk_dialog_run (GTK_DIALOG (dialog1)) == GTK_RESPONSE_YES) + { + gconf_client_set_bool(ws_gui_app->client, + path, + TRUE, + NULL); + } + else + { + gconf_client_set_bool(ws_gui_app->client, + path, + FALSE, + NULL); + } + gtk_widget_destroy (dialog1); + g_free(path); + path = NULL; + + path = g_strconcat(GCONF_PATH, "/", tmp, "/optimized", NULL); + + dialog2 = gtk_message_dialog_new( + GTK_WINDOW(ws_gui_app->ws_gui_hildon_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + _("ws_ni_dictionaries_optimalization_question")); + + gtk_widget_show_all(GTK_WIDGET(dialog2)); + + if (gtk_dialog_run (GTK_DIALOG (dialog2)) == GTK_RESPONSE_YES) + { + gconf_client_set_bool(ws_gui_app->client, + path, + TRUE, + NULL); + } + else + { + gconf_client_set_bool(ws_gui_app->client, + path, + FALSE, + NULL); + } + gtk_widget_destroy (dialog2); + + if(ws_gui_app->ws_gui_history->len > 0) + { + ws_gui_clear_array(ws_gui_app->ws_gui_history); + ws_gui_clear_array(ws_gui_app->ws_gui_history_list); + ws_gui_clear_array(ws_gui_app->ws_gui_history_iter); + ws_gui_app->ws_gui_history_cur_pos = -1; + } + ws_gui_check_history(ws_gui_app); + + ws_dbus_notify(ws_gui_app->dbus_data, + WS_DBUS_INFO_CONFIG_CHANGED); + + return TRUE; +} + +/** this function creates dialog popup window which allows to remove dictionary + * which is no longer used + * + * @param menuitem - the object which received the signal + * @param user_data - set when the signal handler was connected + */ +void ws_gui_dictionary_remover(GtkMenuItem *menuitem, gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + GtkWidget *dialog1; + GtkWidget *dialog_vbox1; + GtkWidget *scrolledwindow1; + GtkWidget *viewport1; + GtkWidget *vbox1; + GtkWidget *checkbutton; + GtkWidget *cancel_button; + GtkWidget *ok_button; + guint i =0; + gchar* string; + gchar* path; + const gchar* name; + GArray *checkboxes; + + checkboxes = g_array_new (TRUE, TRUE, sizeof(GtkWidget*)); + + if (gconf_client_dir_exists(ws_gui_app->client, GCONF_PATH, NULL) + == TRUE) + { + ws_gui_app->directories = gconf_client_all_dirs( + ws_gui_app->client, + GCONF_PATH, + NULL); + } + else + { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, + "\n.::GUI::. /apps/WhiteStork/Dictionaries does not exist!!"); + } + + dialog1 = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (dialog1), + (_("ws_ti_remove_dictionaries_title"))); + gtk_window_set_type_hint (GTK_WINDOW (dialog1), + GDK_WINDOW_TYPE_HINT_DIALOG); + gtk_window_set_default_size(GTK_WINDOW (dialog1), 300, 200); + + dialog_vbox1 = GTK_DIALOG (dialog1)->vbox; + gtk_widget_show (dialog_vbox1); + + scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow1); + gtk_box_pack_start (GTK_BOX (dialog_vbox1), + scrolledwindow1, + TRUE, + TRUE, + 0); + + viewport1 = gtk_viewport_new (NULL, NULL); + gtk_widget_show (viewport1); + gtk_container_add (GTK_CONTAINER (scrolledwindow1), viewport1); + + vbox1 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox1); + gtk_container_add (GTK_CONTAINER (viewport1), vbox1); + + for (i=0; i< g_slist_length(ws_gui_app->directories);i++) + { + string = (gchar*)g_slist_nth_data(ws_gui_app->directories, i); + name = g_path_get_basename(string); + checkbutton = gtk_check_button_new_with_label(name); + + g_array_append_val(checkboxes, checkbutton); + gtk_box_pack_start (GTK_BOX (vbox1), + checkbutton, + FALSE, + FALSE, + 0); + + if (strcmp(name, "bookmarks") == 0) + { + gtk_widget_set_sensitive(GTK_WIDGET(checkbutton), FALSE); + } + gtk_widget_show (checkbutton); + } + + cancel_button = gtk_button_new_from_stock (_("ws_db_cancel")); + gtk_widget_show (cancel_button); + gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), + cancel_button, + GTK_RESPONSE_CANCEL); + + ok_button = gtk_button_new_from_stock + (_("ws_bd_remove_dictionaries_remove_selected")); + gtk_widget_show (ok_button); + gtk_dialog_add_action_widget(GTK_DIALOG (dialog1), + ok_button, + GTK_RESPONSE_OK); + + i = gtk_dialog_run(GTK_DIALOG(dialog1)); + + if (i == GTK_RESPONSE_OK) + { + for(i=0;i<(checkboxes->len);i++) + { + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( + g_array_index(checkboxes, GtkWidget *, i))) == TRUE) + { + + name = gtk_button_get_label(GTK_BUTTON( + g_array_index(checkboxes, GtkWidget *, i))); + path=g_strconcat(GCONF_PATH, "/", name, NULL); + gconf_client_recursive_unset(ws_gui_app->client, + path, + GCONF_UNSET_INCLUDING_SCHEMA_NAMES, + NULL); + } + } + + if(ws_gui_app->ws_gui_history->len >= 0) + { + ws_gui_clear_array(ws_gui_app->ws_gui_history); + ws_gui_clear_array(ws_gui_app->ws_gui_history_list); + ws_gui_clear_array(ws_gui_app->ws_gui_history_iter); + ws_gui_app->ws_gui_history_cur_pos = -1; + } + ws_gui_check_history(ws_gui_app); + + ws_dbus_notify(ws_gui_app->dbus_data, + WS_DBUS_INFO_CONFIG_CHANGED); + gtk_infoprint(GTK_WINDOW( + ws_gui_app->ws_gui_hildon_window), + _("ws_ib_dictionary_removed")); + gtk_widget_destroy (dialog1); + } + else if (i == GTK_RESPONSE_CANCEL) + { + gtk_widget_destroy (dialog1); + } + + g_slist_free(ws_gui_app->directories); +} + +/** this function creates dialog popup window which displays information about + * application (about window) + * + * @param menuitem - the object which received the signal + * @param user_data - set when the signal handler was connected + */ +void ws_gui_about_application(GtkMenuItem *menuitem, gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + gtk_widget_set_sensitive(GTK_WIDGET + (ws_gui_app->ws_gui_hildon_find_toolbar), + FALSE); + + GtkWidget *about_dialog; + GtkWidget *dialog_vbox1; + GtkWidget *vbox1; + GtkWidget *image; + GtkWidget *label2; + GtkWidget *label3; + GtkWidget *label4; + GtkWidget *scrolledwindow; + GtkWidget *textview; + GtkWidget *button1; + + const gchar *ws_version; + + about_dialog = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (about_dialog), + _("ws_ti_about_title")); + gtk_window_set_default_size(GTK_WINDOW (about_dialog), 350, 200); + + dialog_vbox1 = GTK_DIALOG (about_dialog)->vbox; + gtk_widget_show (dialog_vbox1); + + vbox1 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox1); + gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox1, TRUE, TRUE, 0); + + image = gtk_image_new_from_file ("/usr/share/pixmaps/whitestork.png"); + gtk_box_pack_start (GTK_BOX (vbox1), image, TRUE, TRUE, 0); + + label2 = gtk_label_new ("WhiteStork"); + ws_gui_app->p = pango_font_description_from_string("Tahoma 18"); + gtk_widget_modify_font(GTK_WIDGET(label2), ws_gui_app->p); + gtk_label_set_pattern (GTK_LABEL(label2), "__________"); + gtk_box_pack_start (GTK_BOX (vbox1), label2, FALSE, FALSE, 5); + + ws_version = g_strconcat("Maemo Multilingual Dictionary\nver. ", + WS_VERSION, + NULL); + label3 = gtk_label_new_with_mnemonic (_(ws_version)); + ws_gui_app->p = pango_font_description_from_string("Tahoma 12"); + gtk_widget_modify_font(GTK_WIDGET(label3), ws_gui_app->p); + gtk_box_pack_start (GTK_BOX (vbox1), label3, FALSE, FALSE, 5); + gtk_label_set_justify (GTK_LABEL (label3), GTK_JUSTIFY_CENTER); + + label4 = gtk_label_new ("Copyright 2006, ComArch S.A\nAll rights " + "reserved"); + ws_gui_app->p = pango_font_description_from_string("Tahoma 12"); + gtk_widget_modify_font(GTK_WIDGET(label4), ws_gui_app->p); + gtk_box_pack_start (GTK_BOX (vbox1), label4, FALSE, FALSE, 5); + gtk_label_set_justify (GTK_LABEL (label4), GTK_JUSTIFY_CENTER); + + scrolledwindow = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW + (scrolledwindow), + GTK_SHADOW_ETCHED_OUT); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW + (scrolledwindow), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_box_pack_start (GTK_BOX (vbox1), + scrolledwindow, + TRUE, + TRUE, + 0); + + textview = gtk_text_view_new (); + ws_gui_app->p = pango_font_description_from_string("Tahoma 10"); + gtk_widget_modify_font(GTK_WIDGET(textview), ws_gui_app->p); + gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), FALSE); + gtk_text_view_set_left_margin(GTK_TEXT_VIEW(textview), 10); + gtk_text_view_set_right_margin(GTK_TEXT_VIEW(textview), 10); + gtk_container_add (GTK_CONTAINER (scrolledwindow), textview); + gtk_text_buffer_set_text( + gtk_text_view_get_buffer(GTK_TEXT_VIEW (textview)), + "The following third party\ncomponents may be\nincluded" + " depending \non your system configuration:\n\nD-BUS " + "- License information:\nhttp://opensource.org/" + "licenses/academic.php", + -1); + + button1 = gtk_button_new_from_stock(GTK_STOCK_CLOSE); + gtk_dialog_add_action_widget(GTK_DIALOG(about_dialog), + button1, + GTK_RESPONSE_CLOSE); + + gtk_widget_show_all (GTK_WIDGET(about_dialog)); + + if (gtk_dialog_run(GTK_DIALOG(about_dialog)) == GTK_RESPONSE_CLOSE) + { + gtk_widget_destroy(GTK_WIDGET(about_dialog)); + } + + gtk_widget_set_sensitive( + GTK_WIDGET(ws_gui_app->ws_gui_hildon_find_toolbar), + TRUE); +} + +void ws_gui_add_bookmark_dialog(gpointer user_data) +{ + + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + GtkWidget *dialog1; + GtkWidget *dialog_vbox1; + GtkWidget *vbox1; + GtkWidget *hbox1; + GtkWidget *entry1; + GtkWidget *label; + GtkWidget *cancelbutton1; + GtkWidget *okbutton1; + + const gchar *book_word; + + dialog1 = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (dialog1), _("ws_ti_add_bookmark")); + gtk_window_set_default_size(GTK_WINDOW (dialog1), 300, 200); + + dialog_vbox1 = GTK_DIALOG (dialog1)->vbox; + gtk_widget_show (dialog_vbox1); + + vbox1 = gtk_vbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox1, TRUE, TRUE, 5); + + hbox1 = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 5); + + label = gtk_label_new(_("ws_ti_bookmarks_add_question")); + gtk_box_pack_start (GTK_BOX (hbox1), label, TRUE, TRUE, 5); + + entry1 = gtk_entry_new (); + gtk_box_pack_start (GTK_BOX (vbox1), entry1, TRUE, TRUE, 5); + gtk_entry_set_text(GTK_ENTRY(entry1), ws_gui_app->last_word); + gtk_entry_set_alignment (GTK_ENTRY(entry1), 0.5); + gtk_entry_set_editable(GTK_ENTRY(entry1), TRUE); + + cancelbutton1 = gtk_button_new_from_stock (_("ws_db_ok")); + gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), + cancelbutton1, + GTK_RESPONSE_OK); + + okbutton1 = gtk_button_new_from_stock (_("ws_db_cancel")); + gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), + okbutton1, + GTK_RESPONSE_CANCEL); + + gtk_widget_show_all (dialog1); + + if (gtk_dialog_run(GTK_DIALOG(dialog1)) == GTK_RESPONSE_OK) + { + book_word = gtk_entry_get_text(GTK_ENTRY(entry1)); + ws_dbus_client_add_bookmark(ws_gui_app->dbus_data, + (gchar*)book_word, + ws_gui_app->raw_translation->str); + gtk_widget_destroy(GTK_WIDGET(dialog1)); + + } + else + { + gtk_widget_destroy(GTK_WIDGET(dialog1)); + } +} + +void ws_gui_remove_bookmark_dialog(gpointer user_data) +{ + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + GtkWidget *dialog1; + GtkWidget *dialog_vbox1; + GtkWidget *vbox1; + GtkWidget *hbox1; + GtkWidget *entry1; + GtkWidget *label; + GtkWidget *cancelbutton1; + GtkWidget *okbutton1; + + dialog1 = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (dialog1), _("ws_ti_remove_bookmark")); + gtk_window_set_default_size(GTK_WINDOW (dialog1), 300, 200); + + dialog_vbox1 = GTK_DIALOG (dialog1)->vbox; + gtk_widget_show (dialog_vbox1); + + vbox1 = gtk_vbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox1, TRUE, TRUE, 5); + + hbox1 = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 5); + + label = gtk_label_new(_("ws_ni_remove_bookmark_question")); + gtk_box_pack_start (GTK_BOX (hbox1), label, TRUE, TRUE, 5); + + entry1 = gtk_entry_new (); + gtk_box_pack_start (GTK_BOX (vbox1), entry1, TRUE, TRUE, 5); + gtk_entry_set_text(GTK_ENTRY(entry1), ws_gui_app->last_word); + gtk_entry_set_alignment (GTK_ENTRY(entry1), 0.5); + gtk_entry_set_editable(GTK_ENTRY(entry1), FALSE); + + cancelbutton1 = gtk_button_new_from_stock (_("ws_db_ok")); + gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), + cancelbutton1, + GTK_RESPONSE_OK); + + okbutton1 = gtk_button_new_from_stock (_("ws_db_cancel")); + gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), + okbutton1, + GTK_RESPONSE_CANCEL); + + gtk_widget_show_all (dialog1); + + if (gtk_dialog_run(GTK_DIALOG(dialog1)) == GTK_RESPONSE_OK) + { + gtk_widget_destroy(GTK_WIDGET(dialog1)); + gchar* tmp; + + ws_dbus_client_remove_bookmark(ws_gui_app->dbus_data, + ws_gui_app->last_word); + + ws_gui_fill_html(" ", ws_gui_app); + + g_object_get(G_OBJECT(ws_gui_app->ws_gui_hildon_find_toolbar), + "prefix", + &tmp, + NULL); + + if (strlen(tmp) != 0) + { + ws_dbus_client_find_word (ws_gui_app->dbus_data, tmp); + } + else + { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "strlen(tmp)=0"); + gtk_list_store_clear( + ws_gui_app->ws_gui_w_list->ws_gui_store); + } + } + else + { + gtk_widget_destroy(GTK_WIDGET(dialog1)); + } +} + +void ws_gui_list_full_dialog(GtkWidget *widget, GdkEventButton *event, gpointer user_data) { + + WSGuiApp* ws_gui_app=(WSGuiApp*)user_data; + + ws_gui_app->ws_message_dialog = gtk_message_dialog_new( + GTK_WINDOW(ws_gui_app->ws_gui_hildon_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + _("ws_ni_words_list_full")); + + if (gtk_dialog_run( + GTK_DIALOG(ws_gui_app->ws_message_dialog)) + == GTK_RESPONSE_OK) + { + gtk_widget_destroy( + ws_gui_app->ws_message_dialog); + } +} diff --git a/src/manager/COPYING b/src/manager/COPYING new file mode 100644 index 0000000..fb6319b --- /dev/null +++ b/src/manager/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, 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 Lesser 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. + + GNU GENERAL PUBLIC LICENSE + 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. + + + Copyright (C) + + 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. + +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. + + , 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 Lesser General +Public License instead of this License. \ No newline at end of file diff --git a/src/manager/Makefile b/src/manager/Makefile new file mode 100644 index 0000000..409f679 --- /dev/null +++ b/src/manager/Makefile @@ -0,0 +1,36 @@ +CC = gcc +DEBUG = -g -Wall +INCLUDE = ./include +SOURCE = ./src +BINARY = ./bin +INCLUDE_DBUS_WRAPPER = ../../include +LIBS = `pkg-config --libs glib-2.0 gmodule-2.0 libosso gconf-2.0 gthread-2.0` \ + -lbz2 +SQLITE=-DSQLITE=0 +CFLAGS = `pkg-config --cflags glib-2.0 gmodule-2.0 libosso gconf-2.0` \ + -I${INCLUDE} -I${INCLUDE_DBUS_WRAPPER} ${SQLITE} +MAIN_BINARIES = ../../bin +EXECUTABLE = ${BINARY}/WhiteStorkManager + + +SOURCES = ${SOURCE}/*.c +OBJECTS = $(patsubst %.c,%.o,$(wildcard ${SOURCES})) ${MAIN_BINARIES}/ws_dbus.o + +${EXECUTABLE}: ${OBJECTS} + @echo Compiling with ${SQLITE} flag + ${CC} ${DEBUG} -o $@ ${OBJECTS} ${LIBS} ${CFLAGS} + @cp ${EXECUTABLE} ${MAIN_BINARIES} + +%.o: %.c + ${CC} -c -o $@ $< ${DEBUG} ${CFLAGS} + +${MAIN_BINARIES}/ws_dbus.o: + @cd ../dbus_wrapper && make + +.PHONY: clean +clean: + rm -f ${SOURCE}/*.o ${EXECUTABLE} ${SOURCE}/*~ ./*~ + rm -f ${INCLUDE}/*~ +.PHONY: run +run: + run-standalone.sh ./${EXECUTABLE} & diff --git a/src/manager/commit b/src/manager/commit new file mode 100644 index 0000000..11a1e47 --- /dev/null +++ b/src/manager/commit @@ -0,0 +1,2 @@ + * spliting manager code into separate files + * adjust Makefile to new code structure (flexible) diff --git a/src/manager/include/pc-instances.h b/src/manager/include/pc-instances.h new file mode 100644 index 0000000..5cf6b7d --- /dev/null +++ b/src/manager/include/pc-instances.h @@ -0,0 +1,79 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#ifndef _PC_INSTANCES_H_ +#define _PC_INSTANCES_H_ +#ifdef __cplusplus +extern "C" { +#endif + +// stadards headers +#include +#include +#include +// headers with unix types/functions - only for timers and files operations +#include +#include +#include +#include +#include +#include + +//------------------------------------------------------------------------------ +/** \brief Get comandline by which process in /proc tree was invoked. + * + * @param process describes which process from /proc tree we want to check. It + * should be only concrete directory from /proc nothing else. e.g.: /proc/self, + * /proc/8321 etc. Something like /proc or /proc/self is not good. + * @return string containing comandline which has invoked process. If NULL there + * were some problems, possibly parameter were wrong or ther is no such + * a process. + */ +char* get_process_cmdline(char* process); + +//------------------------------------------------------------------------------ +/** \brief Cut from commandline only program file name. + * + * @param cmdline commandline which from which we want to remove options. + * @return string with only program file name, or NULL if there was any problem + */ +char* get_process_program_file(char* cmdline); + +//------------------------------------------------------------------------------ +/** \brief Get file name containing programm executing by current process. + * + * @return file name of program or NULL if there were some problems. + */ +char* get_current_process_program_file(); + +//------------------------------------------------------------------------------ +/** \brief Check if there is another instance of current programm. + * + * @return integer telling how many processes were initiated with the same + * program as curent process. If it is 1, it means there is no other procces. + * If > 1 there is another instance. + */ +int is_already_running_this_application(); + + + +#ifdef __cplusplus +} /* extern "C" { */ +#endif +#endif /* _PC_INSTANCES_H_ */ diff --git a/src/manager/include/untar.h b/src/manager/include/untar.h new file mode 100644 index 0000000..1eb8113 --- /dev/null +++ b/src/manager/include/untar.h @@ -0,0 +1,16 @@ +#ifndef _WS_UNTAR +#define _WS_UNTAR + +#include +/* +Usage example: + +decompress_file ("comn_dictd04_wn.tar.bz2", "./"); + +The above example extracts a given archive, to the current directory +*/ + +gint decompress_file(gchar *in_file, gchar **out_path); + + +#endif /*_WS_UNTAR*/ diff --git a/src/manager/include/ws_manager.h b/src/manager/include/ws_manager.h new file mode 100644 index 0000000..db3b90c --- /dev/null +++ b/src/manager/include/ws_manager.h @@ -0,0 +1,117 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#ifndef _WS_MANAGER +#define _WS_MANAGER + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if SQLITE==0 + #define LIBRARY "/usr/lib/libsqlite.so.0" +#elif SQLITE==3 + #define LIBRARY "/usr/lib/libsqlite3.so.0" +#endif + +#define g_strlen(string) ( NULL == (string) ? 0 : strlen(string) ) + + +struct _WSMngSearchData; +typedef struct _WSMngSearchData WSMngSearchData; + +/** + * Creates new instance of WSMngSearchData structure + *@return new instance of WSMngSearchData structure + */ +WSMngSearchData* ws_manager_create(); + +/** +* \brief Function used to initialize D-BUS +* +*@param data structure stores variables which are need to comunicate by D-BUS. +*/ +void ws_mng_init_dbus (WSMngSearchData *data); + +/** +* \brief Function used to initialize manager +* +* Fuction loads from modules pointers to functions used to service searching +in dictionaries and stores them in WSMngSearchData structure +*@param data pointer to structure WSMngSearchData which stores variables needed +to service manager +*/ +void ws_mng_init (WSMngSearchData *data); + +/** +* \brief Function used to close dictionaries and modules +* +* @param data structure holds pointers to data which need to be freed +from memory +*/ +void ws_mng_close (WSMngSearchData *data); + +/** + * Function used to run and initialize main loop. + *@param serach_data structure which contains all data of program + *@return TRUE if successfully run main loop, FALSE otherwise + */ +gboolean ws_mng_start_main_loop(WSMngSearchData* serach_data); + +struct _WSMngSearchData +{ + GArray* dict; ///< pointer to GArray structure which stores pointers to fuction used to service dictionaries + GArray* modules; ///< pointer to GArray structure which stores pointers to fuction used to service modules loading + gchar* word; ///< word which will be used to search a dictionaries + pthread_t p_thread; ///< a thread in which we serching word list + pthread_t p_thread_trans; ///< a thread in which are searching for translation of word + WSDBusData* dbus_data; ///< a pointer DBUS data + GMainLoop* loop; ///< pointer to main loop + //GModule* library; ///< library used to load modules + GArray* word_list; ///< searched word list + gchar* trans; ///< searched translation + gchar* last_search; ///< last searched word + gboolean search_in_history; ///< flag signalig when search in hisory is commieted + GArray* libraries; /// +#include +#include +#include +#include + + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * Function used to add bookmarks + * @param error error messages + * @param param word and translation of word to adding + * @param user_data structure holding nedded parameters + */ +void ws_mng_add_bookmark(GError *error, GArray* param, gpointer user_data); + +/** + * Function used to remove bookmarks + * @param error error messages + * @param param word and translation of word to remove + * @param user_data structure holding nedded parameters + */ +void ws_mng_remove_bookmark(GError *error, GArray* param, gpointer user_data); + +/** + * Function used to load bookmark module + * @param data structure which holds the loaded module + */ +void ws_mng_load_bookmark(WSMngSearchData* data); + +#ifdef __cplusplus + } +#endif +#endif diff --git a/src/manager/include/ws_mng_callbacks.h b/src/manager/include/ws_mng_callbacks.h new file mode 100644 index 0000000..1cf467a --- /dev/null +++ b/src/manager/include/ws_mng_callbacks.h @@ -0,0 +1,52 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006-2007 ComArch S.A. +*******************************************************************************/ +#ifndef _WS_MANAGER_CALLBACKS +#define _WS_MANAGER_CALLBACKS + +#include +#include +#include +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +void ws_mng_progress_bar (double progress, + gpointer user_data, + EngineStatus error); + +void ws_mng_on_search_word (GError *error, + GArray *word, + gpointer user_data); +void ws_mng_on_search_translation (GError *error, + GArray *word, + gpointer user_data); + +void ws_mng_signal_handling (GError *error, + GArray *signal, + gpointer user_data); + + +#ifdef __cplusplus + } +#endif +#endif diff --git a/src/manager/include/ws_mng_dictionary_utils.h b/src/manager/include/ws_mng_dictionary_utils.h new file mode 100644 index 0000000..1bb1acf --- /dev/null +++ b/src/manager/include/ws_mng_dictionary_utils.h @@ -0,0 +1,53 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006-2007 ComArch S.A. +*******************************************************************************/ +#ifndef _WS_MANAGER_DICTIONARY_UTILS +#define _WS_MANAGER_DICTIONARY_UTILS + +#include +#include +#include +#include +#include + + +#ifdef __cplusplus + extern "C" { +#endif + +/** \brief Extracting compressed dictionary file + * + * @param error after excuting it contains error messages if any was + * @param param parameters given by D-Bus + * @param app_data manager data + */ +void ws_mng_extract_dictionary(GError *error, GArray* param, gpointer app_data); + +/** + * Function used to load dictionaries engines + * @param dict_directory path to dictionaries + * @param data structure which contains all data of program +*/ +void ws_mng_load_dict(GArray* dict_directory, WSMngSearchData* data); + + +#ifdef __cplusplus + } +#endif +#endif diff --git a/src/manager/include/ws_mng_gconf_utils.h b/src/manager/include/ws_mng_gconf_utils.h new file mode 100644 index 0000000..aef8963 --- /dev/null +++ b/src/manager/include/ws_mng_gconf_utils.h @@ -0,0 +1,64 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006-2007 ComArch S.A. +*******************************************************************************/ +#ifndef _WS_MANAGER_GCONF_UTILS +#define _WS_MANAGER_GCONF_UTILS + +#include +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#define GCONF_KEY "/apps/maemo/WhiteStork/Dictionaries" +#define GCONF_LIB_PATH "/apps/maemo/WhiteStork/Engines" + +/** + *Function used to get the dictionaries location read fron GConf + *@return path to dictionaries location + */ +GArray* ws_mng_read_gconf(); + +/** + *Function used to get plugins location read from GConf + *@return libraries location + */ +GArray* ws_mng_get_engines_location(); + + +/** + *Function used to get bookmark library location + *@return path to bookmark location + */ +gchar* ws_mng_get_boomark_location(); + + +/** + *Function used to check if optimized flag in GConf is set + *@param dict path to dictionary file + *@return TRUE if dictionary is optimize, FALSE otherwise + */ +gboolean ws_mng_if_optimized(gchar* dict); + +#ifdef __cplusplus + } +#endif +#endif diff --git a/src/manager/include/ws_mng_searching_threads.h b/src/manager/include/ws_mng_searching_threads.h new file mode 100644 index 0000000..74e2a71 --- /dev/null +++ b/src/manager/include/ws_mng_searching_threads.h @@ -0,0 +1,88 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006-2007 ComArch S.A. +*******************************************************************************/ +#ifndef _WS_MANAGER_SEARCHING_THREADS +#define _WS_MANAGER_SEARCHING_THREADS + +#include +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + + + +/** \brief Function executed by thread - search for word list + * + * @param search_data - pointer to search data structure + * @return - result of thread - always NULL + */ +gpointer ws_mng_search_word (gpointer search_data); + +/** + * \brief Used to return results of found words from threads + * + * @param list word list found in dictionaries + * @param pattern a word which is being search for in dictionaries + * @param user_data data passed to function + * @param error engine status information + */ +void ws_mng_on_found_word (GArray* list, + gchar* pattern, + gpointer user_data, + EngineStatus error); + +/** \brief Function executed by thread - search for particular word + * + * @param search_data - pointer to search data structure + * @return - result of thread - always NULL + */ +gpointer ws_mng_search_translation (gpointer search_data); + +/** + * \brief Used to return results of transaltion from threads + * + * @param translation translation of word found in dictionaries + * @param pattern a word which is being serch for in dictionaries + * @param user_data data passed to function + * @param error engine status information + */ +void ws_mng_on_found_translation (gchar* translation, + gchar* pattern, + gpointer user_data, + EngineStatus error); + +/** + * \brief Function used to compare string. Used in sorting GArray object + * + * @param a first argument to compere + * @param b second argument to compere + * @return result of compare <0 if the second is greater than first 0 if the + * strings are the same >0 if the first string is greater than second + */ +gint ws_mng_compare_strings (gconstpointer a, gconstpointer b); + +void ws_remove_multiple_words(WSMngSearchAtom* user_data); + +#ifdef __cplusplus + } +#endif +#endif diff --git a/src/manager/include/ws_mng_threads_utils.h b/src/manager/include/ws_mng_threads_utils.h new file mode 100644 index 0000000..e499ac1 --- /dev/null +++ b/src/manager/include/ws_mng_threads_utils.h @@ -0,0 +1,49 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006-2007 ComArch S.A. +*******************************************************************************/ +#ifndef _WS_MANAGER_THREADS_UTILS +#define _WS_MANAGER_THREADS_UTILS + +#include + +#ifdef __cplusplus + extern "C" { +#endif + + +struct _WSMngSearchAtom { + WSMngSearchData *data; + gchar *word; + GThread *thread; + + GArray *word_list; + gchar *trans; +}; +typedef struct _WSMngSearchAtom WSMngSearchAtom; + +/* functions for critical sections and thread handling */ +gboolean try_lock_was_locked(WSMngSearchData* data, gchar* fun); +gboolean is_rec_locked(GStaticRecMutex* m); +void stop_if_needed(WSMngSearchAtom* data); +void free_search_atom(WSMngSearchAtom* data); +WSMngSearchAtom *create_search_atom(WSMngSearchData* app_data, gchar* word); +#ifdef __cplusplus + } +#endif +#endif diff --git a/src/manager/src/untar.c b/src/manager/src/untar.c new file mode 100644 index 0000000..165536f --- /dev/null +++ b/src/manager/src/untar.c @@ -0,0 +1,231 @@ +#include +#include +#include +#include +#include +#include +//#include + +#define BLOCK_SIZE 512 +#define BUFFER_SIZE BLOCK_SIZE*32 +#define ASCII_NR(NR) (NR + 0x30) + +typedef struct _TarHeader +{ + gchar name[100]; + gchar mode[8]; + gchar uid[8]; + gchar gid[8]; + gchar size[12]; + gchar mtime[12]; + gchar chksum[8]; + gchar typeflag; + gchar linkname[100]; + gchar magic[6]; + gchar version[2]; + gchar uname[32]; + gchar gname[32]; + gchar devmajor[8]; + gchar devminor[8]; + gchar prefix[155]; + gchar padding[12]; + gchar *gnu_longname; + gchar *gnu_longlink; +} TarHeader; + +typedef enum _RecordType +{ + File = ASCII_NR (0), + ARCHLINK = ASCII_NR (1), + SYMLINK = ASCII_NR (2), + CHARDEV = ASCII_NR (3), + BLOCKDEV = ASCII_NR (4), + Dir = ASCII_NR (5), + FIFO = ASCII_NR (6), + RESERVED = ASCII_NR (7) +} RecordType; + +static gint unpack_file_contents(BZFILE *bz2_file, + TarHeader *header, + gchar *out_name); + + +static gint unpack_file_contents(BZFILE *bz2_file, + TarHeader *header, + gchar *out_name) +{ + gchar* buffer; + guint i; + FILE *file_out; + gulong length; + guint result; + gint bzerror; + + file_out = fopen(out_name, "w"); + + if (file_out == NULL) return -1; + + sscanf(header->size, "%12lo", &length); + g_debug("File size: %ld\n", length); + + for (i=0; i < (length / BLOCK_SIZE); ++i) + { + buffer = (gchar*) g_try_malloc (BLOCK_SIZE * sizeof(gchar)); + + result = BZ2_bzRead ( &bzerror, bz2_file, buffer, BLOCK_SIZE * + sizeof (gchar)); + + fwrite (buffer, BLOCK_SIZE * sizeof(gchar), 1, file_out); + g_free (buffer); + }; + + i = length % BLOCK_SIZE; + + if (i != 0) + { + buffer = (gchar*) g_try_malloc (BLOCK_SIZE * sizeof(gchar)); + + if (buffer == NULL) + { + g_debug("Memory not allocated"); + return -100; + }; + + result = BZ2_bzRead(&bzerror, bz2_file, buffer, + BLOCK_SIZE * sizeof(gchar)); + + if (bzerror == BZ_OK) + { + fwrite (buffer, i * sizeof(gchar), 1, file_out); + } + + else + { + g_debug("bzerror = %d", bzerror); + return -100; + }; + + g_free(buffer); + + }; + + fclose(file_out); + + return 0; +}; + +gint decompress_file (gchar *in_file, gchar **out_path) +{ + FILE *file; + BZFILE *bz2_file; + guint result; + TarHeader* header; + gint bzerror; + gchar* dest_dir = NULL; + header = (TarHeader*) g_try_malloc (BLOCK_SIZE * sizeof(gchar)); + + if (header == NULL) g_debug("\nCould not allocate memory\n"); + + file = fopen (in_file, "rb"); + + if (file != NULL) + + { + bz2_file = BZ2_bzReadOpen (&bzerror, file, 0, 0, NULL, 0); + + if ( bzerror != BZ_OK ) + { + BZ2_bzReadClose ( &bzerror, bz2_file ); + g_debug("There was an error while reading the compressed file\n"); + } + + bzerror = BZ_OK; + while (1) + { + + result = BZ2_bzRead ( &bzerror, bz2_file, header, + BLOCK_SIZE * sizeof (char)); + if ( bzerror == BZ_OK ) + { + if (strlen (header->name) == 0) + { + g_debug("\nFilename length is 0, exitting\n"); + break; + }; + + g_debug("Name: %s\n", header->name); + g_debug("Prefix: %s\n", header->prefix); + + + gchar *temp = g_strconcat (*out_path, + header->name, NULL); + g_debug("Temp path %s\n", temp); + switch (header->typeflag) + { + case File: + g_debug("File\n"); + unpack_file_contents (bz2_file, + header, temp); + break; + + case Dir: + + g_debug("Dir %s\n", temp); + if (mkdir (temp, S_IRUSR| + S_IWUSR|S_IXUSR) != 0) + { + g_debug("Couldn't create directory %s", + temp); + g_free(header); + BZ2_bzReadClose(&bzerror, + bz2_file); + fclose(file); + return -100; + }; + break; + + default: + g_debug("Only files and dirs can be unpacked"); + } + dest_dir = g_strdup(temp); + g_debug("dest_dir %s \n", dest_dir); + g_free (temp); + + } + + else if ( bzerror != BZ_STREAM_END ) + { + g_debug("\nBZ2 READ_CLOSE(stream end) %d\n", bzerror); + BZ2_bzReadClose ( &bzerror, bz2_file ); + break; + } + + else + { + g_debug("\nExitting, error nr %d\n", bzerror); + BZ2_bzReadClose ( &bzerror, bz2_file ); + break; + }; + + }; + + } + else + { + g_debug("There was an error while trying to read the archive file"); + g_free(header); header = NULL; + fclose(file); + return -100; + }; + if (dest_dir != NULL) + { + g_free(*out_path); *out_path = NULL; + *out_path = g_strdup(dest_dir); + g_free(dest_dir); dest_dir = NULL; + } + g_free(header); header = NULL; + fclose(file); + return 100; + + +}; diff --git a/src/manager/src/whitestork.c b/src/manager/src/whitestork.c new file mode 100644 index 0000000..c175569 --- /dev/null +++ b/src/manager/src/whitestork.c @@ -0,0 +1,48 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif +#include +#include +#include +//#include +//#include + +int main (gint argc, gchar** argv) +{ + g_type_init(); + + WSMngSearchData* search_data = ws_manager_create(); + + ws_mng_init_dbus(search_data); + ws_mng_init(search_data); + + ws_mng_start_main_loop(search_data); + + ws_mng_close(search_data); + + //g_free(search_data); + + return 0; +} +#ifdef __cplusplus +} +#endif diff --git a/src/manager/src/ws_manager.c b/src/manager/src/ws_manager.c new file mode 100644 index 0000000..317a893 --- /dev/null +++ b/src/manager/src/ws_manager.c @@ -0,0 +1,335 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#include + +#include +#include +#include +#include +#include +#include + + +/** + * Public function, see ws_manager.h + */ +WSMngSearchData* ws_manager_create() { + g_debug("<--> %s", __FUNCTION__); + WSMngSearchData* tmp = g_try_new(WSMngSearchData, 1); + + if (NULL == tmp) + { + g_debug("Not enough memory !"); + } + return tmp; +} + +/** + * Public function, see ws_manager.h + */ +gboolean ws_mng_start_main_loop(WSMngSearchData* search_data) +{ + g_debug("<--> %s", __FUNCTION__); + search_data->loop = g_main_loop_new (NULL, FALSE); + if (search_data->loop == NULL) + { + g_debug("Couldn't create new g_main_loop for Manager!"); + return FALSE; + } + g_main_loop_run (search_data->loop); + return TRUE; +} + + + + +/** + *Public function, see ws_manager.h + */ +void ws_mng_init_dbus (WSMngSearchData *data) +{ + g_debug("->%s", __FUNCTION__); + + /* create data structure needed to comunicate with dbus wrapper */ + data->dbus_data = ws_dbus_create ("WhiteStorkManager", "v1.0"); + + /* set data used to comunicate with gui */ + ws_dbus_config(data->dbus_data, + WS_DBUS_CONFIG_SERVICE, + "org.maemo.WhiteStorkManager"); + ws_dbus_config(data->dbus_data, + WS_DBUS_CONFIG_OBJECT, + "/org/maemo/WhiteStorkManager"); + ws_dbus_config(data->dbus_data, + WS_DBUS_CONFIG_IFACE, + "org.maemo.WhiteStorkManager"); + ws_dbus_config(data->dbus_data, + WS_DBUS_CONFIG_REMOTE_SERVICE, + "org.maemo.WhiteStorkGui"); + ws_dbus_config(data->dbus_data, + WS_DBUS_CONFIG_REMOTE_OBJECT, + "/org/maemo/WhiteStorkGui"); + ws_dbus_config(data->dbus_data, + WS_DBUS_CONFIG_REMOTE_IFACE, + "org.maemo.WhiteStorkGui"); + + + ws_dbus_add_method (data->dbus_data, "find_word", WS_DBUS_TYPE_STRING, + WS_DBUS_TYPE_INVALID); + + ws_dbus_add_method (data->dbus_data, "find_translation", + WS_DBUS_TYPE_STRING, WS_DBUS_TYPE_INVALID); + + ws_dbus_add_method (data->dbus_data, "signal", WS_DBUS_TYPE_SIGNAL, + WS_DBUS_TYPE_INVALID); + + ws_dbus_add_method (data->dbus_data, "add_bookmark", + WS_DBUS_TYPE_STRING, WS_DBUS_TYPE_STRING, + WS_DBUS_TYPE_INVALID); + ws_dbus_add_method (data->dbus_data, "remove_bookmark", + WS_DBUS_TYPE_STRING, WS_DBUS_TYPE_INVALID); + + ws_dbus_add_method (data->dbus_data, "extract_dictionary", + WS_DBUS_TYPE_STRING, WS_DBUS_TYPE_INVALID); + + /* set callback for find word signal */ + ws_dbus_set_cb(data->dbus_data, + "find_word", + ws_mng_on_search_word, + data); + + /* set callback for find translation signal */ + ws_dbus_set_cb(data->dbus_data, + "find_translation", + ws_mng_on_search_translation, + data); + + /* set callback for close program signal */ + ws_dbus_set_cb(data->dbus_data, + "signal", + ws_mng_signal_handling, + data); + + /* set callback for add bookmarks signal */ + ws_dbus_set_cb(data->dbus_data, + "add_bookmark", + ws_mng_add_bookmark, + data); + + /* set callback for remove bookmarks signal */ + ws_dbus_set_cb(data->dbus_data, + "remove_bookmark", + ws_mng_remove_bookmark, + data); + + /* set callback for extracting dictionary */ + ws_dbus_set_cb(data->dbus_data, + "extract_dictionary", + ws_mng_extract_dictionary, + data); + + ws_dbus_connect(data->dbus_data); + + + g_debug("<-%s", __FUNCTION__); +} + + +/** + *Public fuction, see ws_manager.h + */ +void ws_mng_init (WSMngSearchData *data) +{ + g_debug("->%s", __FUNCTION__); + data->dict = g_array_new(TRUE, TRUE, sizeof(Engine *)); + data->modules = g_array_new(TRUE, TRUE, sizeof(EngineModule)); + data->libraries = g_array_new(TRUE, TRUE, sizeof(GModule*)); + data->word_list = NULL; + data->last_search = NULL; + data->trans = NULL; + data->search_in_history = FALSE; + data->word = NULL; + data->bookmark = NULL; + data->bookmark_mode = FALSE; + /* added by Dariusz Wiechecki + * mutex initialization */ + data->action_working = (GStaticMutex*)g_try_malloc(sizeof(GStaticMutex)); + data->thread_creation = (GStaticMutex*)g_try_malloc(sizeof(GStaticMutex)); + data->action_stop = (GStaticRecMutex*)g_try_malloc(sizeof(GStaticRecMutex)); + g_assert(NULL != (data->action_working) ); + g_assert(NULL != (data->action_stop) ); + g_static_mutex_init (data->action_working); + g_static_mutex_init (data->thread_creation); + g_static_rec_mutex_init (data->action_stop); + /* initialize static stop_if_needed function mutex*/ + stop_if_needed (NULL); + /* initialize GThread structure */ + //data->action_thread = NULL; + + #ifdef SQLITE + if (g_file_test(LIBRARY, + G_FILE_TEST_EXISTS) == FALSE) + { + ws_dbus_notify(data->dbus_data, WS_DBUS_LOAD_BOOKMARK_FAILED); + } + #endif + + GArray* dict_directory = ws_mng_read_gconf(); //paths to dictionaries + gint i = 0; + + data->library_path = ws_mng_get_engines_location(); + //load the engine function + for (i = 0; i < data->library_path->len; i++) + { + gchar* path= g_array_index(data->library_path, gchar*, i); + GModule* library = g_module_open(path, G_MODULE_BIND_LAZY); + g_array_append_val(data->libraries, library); + g_debug("%p library pinter %d iter", library, i); + //g_free(path); + } + //data->library = g_module_open(library_to_path, G_MODULE_BIND_LAZY); + + for (i=0; ilibraries->len; i++) + { + getting_additional get_functions = NULL; + //get_functions = NULL; + //data->library + g_debug("%p", g_array_index(data->libraries, GModule*, i)); + g_module_symbol(g_array_index(data->libraries, GModule*, i), + "engine_global_functions", + (gpointer)&get_functions); + g_debug("%d %p", i, &get_functions); + if (get_functions == NULL) //check if function was loaded + { + ws_dbus_notify(data->dbus_data, + WS_DBUS_ERROR_ENGINE_NOT_FOUND); + for (i=0; ilen; i++) + { + g_free(g_array_index(dict_directory, gchar*, i)); + } + g_array_free(dict_directory, TRUE); + ws_mng_close(data); + exit(0); //exit program + } + EngineModule module = get_functions(); + //tmp = (EngineModule*) g_memdup(&module, sizeof(EngineModule)); + //module = (EngineModule**) &tmp; + g_array_append_val(data->modules, module); + + } + + ws_mng_load_bookmark(data); + if (dict_directory->len > 0) + { + ws_dbus_notify(data->dbus_data, WS_DBUS_INFO_CACHING); + + ws_mng_load_dict(dict_directory, data); + guint i = 0; + g_debug("Trace bookmark engine %p", data->bookmark); + for (i=0; idict->len; i++) + { + g_debug("dict engines at %p", + g_array_index(data->dict, Engine*, i)); + } + ws_dbus_notify(data->dbus_data, + WS_DBUS_INFO_CACHING_FINISHED); + } + else + { + ws_dbus_notify(data->dbus_data, + WS_DBUS_ERROR_FILE_NOT_FOUND); + } + for (i=0; ilen; i++) + { + g_free(g_array_index(dict_directory, gchar*, i)); + } + g_array_free(dict_directory, TRUE); + g_debug("<-%s", __FUNCTION__); +} + +/** + *Public function, see ws_manager.h + */ +void ws_mng_close (WSMngSearchData *data) +{ + int i = 0; + g_debug("->%s", __FUNCTION__); + + ws_dbus_destroy (data->dbus_data); // deinitialization of dbus + if (data->bookmark != NULL) + { + dict_eng_destroy(data->bookmark); + } + + for (i = 0; i < data->dict->len; i++) + { + //free memory taken by engine + dict_eng_destroy(g_array_index (data->dict, Engine*,i)); + } + g_array_free(data->dict, TRUE); + + /*for (i=0; iword_list->len; i++) + { + g_free(g_array_index(data->word_list, gchar*, i)); + } + + g_array_free(data->word_list, TRUE);*/ + + //free memory used by modules + //g_array_free(data->modules, TRUE); + //free memory taken by dictionaries + g_free(data->last_search); + + g_free(data->loop); + + g_static_mutex_free(data->thread_creation); + g_static_mutex_free(data->action_working); + g_static_rec_mutex_free(data->action_stop); + /*if (data->word != NULL) g_free(data->word);*/ + + //if (data->trans != NULL) g_free(data->trans); + + for (i=0; ilibrary_path->len; i++) + { + g_free(g_array_index(data->library_path, gchar*, i)); + } + g_array_free(data->library_path, TRUE); + + g_array_free(data->modules, TRUE); data->modules = NULL; + + for (i=0; i< data->libraries->len; i++) + { + if (g_array_index(data->libraries, GModule*, i) != NULL) + { + //close library + g_module_close(g_array_index(data->libraries, + GModule*, i)); + } + + } + + g_array_free(data->libraries, TRUE); + + g_free(data); + + g_debug("<-%s", __FUNCTION__); +} + + diff --git a/src/manager/src/ws_mng_bookmarks_utils.c b/src/manager/src/ws_mng_bookmarks_utils.c new file mode 100644 index 0000000..3a6e14a --- /dev/null +++ b/src/manager/src/ws_mng_bookmarks_utils.c @@ -0,0 +1,167 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#include + +/** + *Function used to add bookmarks + *@param error error messages + *@param param word and translation of word to adding + *@param user_data structure holding nedded parameters + */ +void ws_mng_add_bookmark(GError *error, GArray* param, gpointer user_data) +{ + g_debug("->%s", __FUNCTION__); + + WSMngSearchData* data = (WSMngSearchData *) user_data; + osso_rpc_t* osso_data = NULL; + osso_rpc_t* osso_data_trans = NULL; + gchar* word = NULL; + gchar* translation = NULL; + //get the word passed by dbus + if (data->bookmark != NULL) + { + //g_debug("adding bookmarks...%p locataion", data->bookmark); + osso_data = &g_array_index (param, osso_rpc_t, 0); + word = g_strdup(osso_data->value.s); + osso_data_trans = &g_array_index (param, osso_rpc_t, 1); + translation = g_strdup(osso_data_trans->value.s); + //do not free translation and word + gboolean is_added = dict_eng_add_word(data->bookmark, + word, translation); + if (is_added == TRUE) + { + ws_dbus_notify(data->dbus_data, + WS_DBUS_BOOKMARKS_ADDED_OK); + } + else + { + ws_dbus_notify(data->dbus_data, + WS_DBUS_BOOKMARKS_ADDED_FAIL); + } + osso_rpc_free_val(osso_data); + g_free(translation); + g_free(word); + } + else + { + ws_dbus_notify(data->dbus_data, + WS_DBUS_BOOKMARKS_ADDED_FAIL); + g_debug("-> %s - there is no bookmark engine!\n", __FUNCTION__); + } + g_debug("<-%s", __FUNCTION__); +} + +/** + *Function used to remove bookmarks + *@param error error messages + *@param param word and translation of word to remove + *@param user_data structure holding nedded parameters + */ +void ws_mng_remove_bookmark(GError *error, GArray* param, gpointer user_data) +{ + g_debug("->%s", __FUNCTION__); + + WSMngSearchData* data = (WSMngSearchData *) user_data; + osso_rpc_t* osso_data = NULL; + gchar* word = NULL; + //get the word passed by dbus + if (data->bookmark != NULL) + { + g_debug("removing bookmarks..."); + osso_data = &g_array_index(param, osso_rpc_t, 0); + word = g_strdup(osso_data->value.s); + + gboolean is_remove = dict_eng_remove_word(data->bookmark, word); + if (is_remove == TRUE) + { + ws_dbus_notify(data->dbus_data, + WS_DBUS_BOOKMARKS_REMOVED_OK); + } + else + { + ws_dbus_notify(data->dbus_data, + WS_DBUS_BOOKMARKS_REMOVED_FAIL); + } + + osso_rpc_free_val(osso_data); + } + else + { + ws_dbus_notify(data->dbus_data, + WS_DBUS_BOOKMARKS_ADDED_FAIL); + g_debug("-> %s - there is no bookmark engine!\n", __FUNCTION__); + } + g_debug("<-%s", __FUNCTION__); +} + + +/** + *Function used to load bookmark module + *@param data structure which holds the loaded module + */ +void ws_mng_load_bookmark(WSMngSearchData* data) +{ + g_debug("->%s", __FUNCTION__); + guint i = 0; + data->bookmark = NULL; + gchar* current_directory = ws_mng_get_boomark_location(); + if (current_directory != NULL) + { + #ifdef SQLITE + if (g_file_test(LIBRARY, G_FILE_TEST_EXISTS)) + { + #endif + for (i=0; imodules->len; i++) + { + if (dict_eng_module_check( + g_array_index(data->modules, EngineModule, i), + current_directory) == TRUE) + { + data->bookmark = + dict_eng_module_create_ext( + g_array_index(data->modules, + EngineModule, + i), + current_directory, + ENGINE_CREATE, + ws_mng_progress_bar, + data, + 0.02); + dict_eng_set_callback(data->bookmark, + ENGINE_WORD_LIST_SIGNAL, + ws_mng_on_found_word, + data); + //set callback for return translation + dict_eng_set_callback(data->bookmark, + ENGINE_WORD_TRANSLATION_SIGNAL, + ws_mng_on_found_translation, + data); + + break; + } + } + + #ifdef SQLITE + } + #endif + g_free(current_directory); + } + g_debug("<-%s", __FUNCTION__); +} diff --git a/src/manager/src/ws_mng_callbacks.c b/src/manager/src/ws_mng_callbacks.c new file mode 100644 index 0000000..9db25b2 --- /dev/null +++ b/src/manager/src/ws_mng_callbacks.c @@ -0,0 +1,249 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#include + +/** + * Function used to send inforamtion about progress of caching XDXF file to UI + * @param progess how much file is cached + * @param user_data data needed to send information to UI + * @param error error messages + */ +void ws_mng_progress_bar(double progress, + gpointer user_data, + EngineStatus error + ) +{ + g_debug("<--> %s - progress=%f", __FUNCTION__, progress); + WSMngSearchData *data = (WSMngSearchData *) user_data; + ws_dbus_server_update_progressbar(data->dbus_data, progress); +} + + + +/** +* \brief Called when find word event occurs +* +* @param word word to search +* @param error error messages +* @param user_data user data passed to function +*/ +void ws_mng_on_search_word(GError *error, + GArray *word, + gpointer user_data + ) +{ + g_debug("[L-word] -> %s: reading parameters...", __FUNCTION__); + WSMngSearchData *search = (WSMngSearchData *) user_data; + osso_rpc_t* osso_data = NULL; + + /* ---> CRITICAL SECTION for this function */ + g_static_mutex_lock( search->thread_creation ); + + /* get the word passed by dbus */ + osso_data = &g_array_index (word, osso_rpc_t, 0); + gchar* tmp = NULL; + if (( g_utf8_strchr(osso_data->value.s, -1, '*') == NULL ) && + ( g_utf8_strchr(osso_data->value.s, -1, '?') == NULL )) + { + tmp = g_strconcat(osso_data->value.s, "*", NULL); + } + else + { + tmp = g_strdup(osso_data->value.s); + } + + /* create and init searching data - separate for each thread */ + WSMngSearchAtom* search_data = NULL; + search_data = create_search_atom(search, tmp); + g_free(tmp); + if (NULL == search_data) + { + return; + } + + g_debug("[L-word] creating GThread object..."); + search_data->thread = g_thread_create (ws_mng_search_word, + search_data, + TRUE, + NULL); + g_debug("[L-word] GThread object created. Exiting from CREATOR."); + + g_static_mutex_unlock( search->thread_creation ); + /* <--- end of CRITICAL SECTION for this function */ + + g_debug("[L-word] <-%s", __FUNCTION__); +} + +/** +* \brief Called when find translation event occurs +* +* @param word word to search +* @param error error messages +* @param user_data user data passed to function +*/ +void ws_mng_on_search_translation (GError *error, + GArray *word, + gpointer user_data) +{ + g_debug("[L-tran] ->%s", __FUNCTION__); + + WSMngSearchData *data = (WSMngSearchData *) user_data; + + /* ---> CRITICAL SECTION for this function */ + g_static_mutex_lock(data->thread_creation); + + /* get the data sended by dbus */ + osso_rpc_t *osso_data; + osso_data = &g_array_index (word, osso_rpc_t, 0); + + /* create and init searching data - separate for each thread */ + WSMngSearchAtom* search_data = NULL; + search_data = create_search_atom(data, osso_data->value.s); + if (NULL == search_data) + { + return; + } + + g_debug("[L-tran] creating GThread object..."); + search_data->thread = g_thread_create (ws_mng_search_translation, + search_data, + TRUE, + NULL); + g_debug("[L-tran] GThread object created. Exiting from CREATOR."); + + + g_static_mutex_unlock(data->thread_creation); + /* <--- end of CRITICAL SECTION for this function */ + + g_debug("[L-tran] <-%s", __FUNCTION__); +} + + +/** +* \brief Function used for handling signals sent by user interface +* +* @param error error messages +* @param signal type of signal +* @param user_data data passed to function +*/ +void ws_mng_signal_handling(GError *error, GArray *signal, gpointer user_data) +{ + g_debug("->%s", __FUNCTION__); + osso_rpc_t osss_data; + osss_data = g_array_index (signal, osso_rpc_t, 0); + WSMngSearchData *data = (WSMngSearchData *) user_data; + gint i = 0; + switch(osss_data.value.i) + { + case WS_DBUS_INFO_TERMINATE: + /* added by Dariusz Wiechecki + * canceling GLib Threads */ + if (try_lock_was_locked(data,(gchar*)__FUNCTION__)) + { + g_printf("[S] STOP ACTION! %s\n",__FUNCTION__); + g_static_rec_mutex_lock(data->action_stop); + g_static_mutex_lock(data->action_working); + } + g_static_rec_mutex_unlock(data->action_stop); + ws_dbus_notify(data->dbus_data, + WS_DBUS_WORDS_LIST_FINISHED); + ws_dbus_notify(data->dbus_data, + WS_DBUS_TRANSLATION_FINISHED); + g_static_mutex_unlock(data->action_working); + g_main_loop_quit (data->loop); + break; + case WS_DBUS_INFO_STOP_SEARCH: + /* added by Dariusz Wiechecki + * canceling GLib Threads */ + if (try_lock_was_locked(data,(gchar*)__FUNCTION__)) + { + g_printf("[S] STOP ACTION! %s\n",__FUNCTION__); + g_static_rec_mutex_lock(data->action_stop); + g_static_mutex_lock(data->action_working); + } + g_static_rec_mutex_unlock(data->action_stop); + ws_dbus_notify(data->dbus_data, + WS_DBUS_WORDS_LIST_FINISHED); + ws_dbus_notify(data->dbus_data, + WS_DBUS_TRANSLATION_FINISHED); + g_static_mutex_unlock(data->action_working); + break; + + case WS_DBUS_INFO_CONFIG_CHANGED: + ws_dbus_notify(data->dbus_data, WS_DBUS_INFO_CACHING); + + for (i=0; idict->len; i++) + { + if (g_array_index(data->dict, Engine*,i) != NULL) + { + dict_eng_destroy( + g_array_index( + data->dict, Engine*,i + ) + ); + } + } + g_array_free(data->dict, TRUE); + + data->dict = g_array_new (TRUE, TRUE, sizeof(Engine*));; + //paths to directories + GArray* dir_array = ws_mng_read_gconf(); + //fill the table again with new dicnioraries + ws_mng_load_dict(dir_array, data); + //if there is no dictionary selected + // signal this fact to gui + if (data->dict->len <= 0) + { + ws_dbus_notify(data->dbus_data, + WS_DBUS_INFO_CACHING_FINISHED); + ws_dbus_notify(data->dbus_data, + WS_DBUS_ERROR_FILE_NOT_FOUND); + }else + { + //if there was typed word search for word list + if (data->last_search != NULL) + { + data->word_list = g_array_new(TRUE, TRUE, + sizeof(gchar*));//creating new word list + + g_free(data->word); data->word = NULL; + data->word = g_strdup(data->last_search); + } + //signal end of dictionary load to gui + ws_dbus_notify(data->dbus_data, + WS_DBUS_INFO_CACHING_FINISHED); + } + //free memory + for (i=0; ilen; i++) + { + g_free(g_array_index(dir_array, gchar*, i)); + } + g_array_free(dir_array, TRUE); + break; + case WS_DBUS_BOOKMARK_MODE_ON: + data->bookmark_mode = TRUE; + break; + + case WS_DBUS_BOOKMARK_MODE_OFF: + data->bookmark_mode = FALSE; + break; + } + g_debug("<-%s", __FUNCTION__); +} diff --git a/src/manager/src/ws_mng_dictionary_utils.c b/src/manager/src/ws_mng_dictionary_utils.c new file mode 100644 index 0000000..e39f078 --- /dev/null +++ b/src/manager/src/ws_mng_dictionary_utils.c @@ -0,0 +1,135 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#include + +void ws_mng_extract_dictionary(GError *error, + GArray* param, + gpointer user_data) +{ + g_debug("->%s", __FUNCTION__); + WSMngSearchData *data = (WSMngSearchData *) user_data; + osso_rpc_t *osso_data; + //get the data sended by dbus + osso_data = &g_array_index (param, osso_rpc_t, 0); + //get the path sended by dbus + gchar* path = g_strdup(osso_data->value.s); + gint result = -1; + + gchar* dest = NULL; + if (path != NULL) + { + gint count = 0; + gchar** tmp = g_strsplit(path, + "/", + 0); + while(tmp[count++] != NULL); + dest = g_strndup(path, g_strlen(path)- g_strlen(tmp[count -2])); + g_strfreev(tmp); + } + if (dest != NULL) + { ws_dbus_notify(data->dbus_data, WS_DBUS_EXTRACT_FILE); + result = decompress_file(path, &dest); + ws_dbus_notify(data->dbus_data, WS_DBUS_EXTRACT_FILE_FINISHED); + } + + if (result > 0) + { + ws_dbus_server_return_extracted_dict(data->dbus_data, dest); + } + else + { + dest = ""; + ws_dbus_server_return_extracted_dict(data->dbus_data, dest); + } + + g_free(path); + g_debug("<-%s", __FUNCTION__); +} + + +/** + *Function used to load dictionaries engines + *@param dict_directory path to dictionaries + *@param data structure which contains all data of program +*/ +void ws_mng_load_dict(GArray* dict_directory, WSMngSearchData* data) +{ + + gint i = 0; + gint j = 0; + Engine* xdxf = NULL; + g_debug("->%s", __FUNCTION__); + for (i =0; ilen; i++) + { + gchar* current_directory = strdup(g_array_index(dict_directory, + gchar*, + i) + ); + for (j=0; jmodules->len; j++) + { + if (dict_eng_module_check(g_array_index(data->modules, + EngineModule, + j), + current_directory) == TRUE) + { + if(ws_mng_if_optimized(current_directory)) + { + xdxf = dict_eng_module_create_ext( + g_array_index(data->modules, + EngineModule, + j), + current_directory, + ENGINE_CREATE, + ws_mng_progress_bar, + data, + 0.02); //create engine module + } + else + { + xdxf = dict_eng_module_create_ext( + g_array_index(data->modules, + EngineModule, + j), + current_directory, + ENGINE_NO, + ws_mng_progress_bar, + data, + 0.02); //create engine module + } + //set callback for return words list function + dict_eng_set_callback(xdxf, + ENGINE_WORD_LIST_SIGNAL, + ws_mng_on_found_word, + data); + //set callback for return translation + dict_eng_set_callback(xdxf, + ENGINE_WORD_TRANSLATION_SIGNAL, + ws_mng_on_found_translation, + data); + //adding newly created engine to Garray + g_array_append_val (data->dict, xdxf); + g_free(current_directory); + } + } + } + g_debug("<-%s", __FUNCTION__); +} + + diff --git a/src/manager/src/ws_mng_gconf_utils.c b/src/manager/src/ws_mng_gconf_utils.c new file mode 100644 index 0000000..92d7371 --- /dev/null +++ b/src/manager/src/ws_mng_gconf_utils.c @@ -0,0 +1,257 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#include + + +/** + *Function used to get the dictionaries location read fron GConf + *@return path to dictionaries location + */ +GArray* ws_mng_read_gconf() +{ + //g_type_init(); + g_debug("--%s", __FUNCTION__); + GConfClient* client = NULL; + GArray* path_to_dir = g_array_new(TRUE, TRUE, sizeof(gchar *)); + gchar* path = NULL; + //gchar* key_value = NULL; + gboolean key_active = FALSE; + gint i = 0; + + client = gconf_client_get_default(); + GSList* list = gconf_client_all_dirs(client, GCONF_KEY, NULL); + for (i=0; i%s", __FUNCTION__); + GConfClient* client = NULL; + GArray* path_to_dir = g_array_new(TRUE, TRUE, sizeof(gchar *)); + gchar* path = NULL; + gint i = 0; + client = gconf_client_get_default(); + GSList* list = gconf_client_all_dirs(client, GCONF_LIB_PATH, NULL); + for (i=0; i%s", __FUNCTION__); + //g_type_init(); + GConfClient* client = NULL; + gchar* path = NULL; + guint i = 0; + client = gconf_client_get_default(); + GSList* list = gconf_client_all_dirs(client, GCONF_KEY, NULL); + for (i=0; i%s", __FUNCTION__); + + GConfClient* client; + gchar* path = NULL; + gboolean key_optimized = FALSE; + gboolean key_found = FALSE; + gint i = 0; + + client = gconf_client_get_default(); + GSList* list = gconf_client_all_dirs(client, GCONF_KEY, NULL); + for (i=0; i + +/** +* \brief Function used to run search for word engine in threads +* +* @param data required data for search word event +* @return gpointer return value +*/ +gpointer ws_mng_search_word (gpointer user_data) +{ + g_debug("[T-word] %s: Entering thread...", __FUNCTION__); + WSMngSearchAtom *search_atom = (WSMngSearchAtom*)user_data; + WSMngSearchData *search = search_atom->data; + + /* enter into CRITICAL SECTION */ + if (try_lock_was_locked(search,(gchar*)__FUNCTION__)) + { + g_printf("[T-word] STOP mutex is locked! Aborting others!"); + g_static_rec_mutex_lock(search->action_stop); + g_static_mutex_lock(search->action_working); + } + g_static_rec_mutex_unlock(search->action_stop); + + /* if another thread was run after this one - exit */ + stop_if_needed(search_atom); + + g_debug("[T-word] %s - from now this thread is \'singleton\' ", + __FUNCTION__ + ); + ws_dbus_notify(search->dbus_data, WS_DBUS_WORDS_LIST_STARTED); + /* creating new GArray for word list */ + search_atom->word_list = g_array_new(TRUE, TRUE, sizeof(gchar*)); + + g_debug("[T-word] %s - start searching... ",__FUNCTION__); + if (search->bookmark_mode) + { /* search only in user bookmarks */ + dict_eng_search_word_list(search->bookmark, + search_atom->word, + search_atom); + } + else + { /* search for word in each dictionary */ + gint i = 0; + for (i = 0; i < search->dict->len; i++) + { + if (NULL == g_array_index(search->dict, Engine *, i)) + { + continue; + } + + stop_if_needed(search_atom); + Engine* dict = g_array_index(search->dict,Engine *,i); + dict_eng_search_word_list(dict, search_atom->word, search_atom); + } + } + g_debug("[T-word] %s - searching finished.",__FUNCTION__); + + /* if another thread was run after this one - exit */ + stop_if_needed(search_atom); + + /* sort and cleaning words list - only if there were more than one + * dictionary loaded */ + if ((FALSE == search->bookmark_mode) || (1 < search->dict->len)) + { + g_array_sort(search_atom->word_list, ws_mng_compare_strings); + ws_remove_multiple_words(search_atom); + } + + /* if another thread was run after this one - exit */ + stop_if_needed(search_atom); + + ws_dbus_server_return_words(search->dbus_data, search_atom->word_list); + ws_dbus_notify(search->dbus_data, WS_DBUS_WORDS_LIST_FINISHED); + + /* free memory used by each word from word list */ + gint i = 0; + for (; i < search_atom->word_list->len; i++) + { + g_free(g_array_index(search_atom->word_list,gchar* ,i)); + } + + /* free memory used by GArray */ + g_array_free(search_atom->word_list, TRUE); + search_atom->word_list = NULL; + + g_free(search_atom->word); + g_free(search_atom); + g_debug("[T-word] %s - leaving thread!", __FUNCTION__); + g_static_mutex_unlock(search->action_working); + return NULL; +} + +/** +* \brief Used to return results of found word from threads +* +* @param list word list found in dictionaries +* @param pattern a word which is being search for in dictionaries +* @param user_data data passed to function +* @param error engine status information +*/ +void ws_mng_on_found_word(GArray* list, + gchar* pattern, + gpointer user_data, + EngineStatus error) +{ + g_debug("[T-word-ret]-> %s", __FUNCTION__); + + WSMngSearchAtom* search_atom = (WSMngSearchAtom*)user_data; + static gint i = 0; + for (i = 0; i < list->len; i++) + { + /* copy word found by search engine */ + gchar* new_word = g_strdup(g_array_index(list, gchar*, i)); + //g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "new_word: %s", new_word); + g_array_append_val(search_atom->word_list, new_word); + + } + + g_debug("[T-word-ret]<- %s", __FUNCTION__); +} + +/** +* \brief Function used to run search for transaltion of word engine in threads +* +* @param data required data for search translation +* @return gpointer return value +*/ +gpointer ws_mng_search_translation (gpointer data) +{ + g_debug("[T-tran] %s: Entering thread...", __FUNCTION__); + WSMngSearchAtom* search_atom = (WSMngSearchAtom*)data; + WSMngSearchData* search = search_atom->data; + + /* ---> CRITICAL SECTION for this function */ + if (try_lock_was_locked(search,(gchar*)__FUNCTION__)) + { + g_printf("[T-tran] STOP mutex is locked! Aborting others!"); + g_static_rec_mutex_lock(search->action_stop); + g_static_mutex_lock(search->action_working); + } + g_static_rec_mutex_unlock(search->action_stop); + /* if another thread was run after this one - exit */ + stop_if_needed(search_atom); + + g_debug("[T-tran] %s - from now this thread is \'singleton\' ", + __FUNCTION__ + ); + ws_dbus_notify(search->dbus_data, WS_DBUS_TRANSLATION_STARTED); + + /* run search for translation for every dictionary */ + if (search->bookmark_mode) + { + dict_eng_search_word_translation(search->bookmark, + search_atom->word, + search_atom); + } + else + { + gint i; + for (i = 0; i < search->dict->len; i++) + { + stop_if_needed(search_atom); + if (NULL == g_array_index(search->dict, Engine*, i) ) + { + continue; + } + dict_eng_search_word_translation( + g_array_index(search->dict, Engine*, i), + search_atom->word, + search_atom); + } + } + g_debug("[T-tran] %s - searching finished.",__FUNCTION__); + + /* if another thread was run after this one - exit */ + stop_if_needed(search_atom); + + /* send translation to gui */ + ws_dbus_server_return_translations(search->dbus_data, search_atom->trans); + ws_dbus_notify(search->dbus_data, WS_DBUS_TRANSLATION_FINISHED); + + g_free(search->trans); + search->trans = NULL; + + g_debug("[T-word] %s - leaving thread!", __FUNCTION__); + g_static_mutex_unlock(search->action_working); + return NULL; +} + +/** +* \brief Used to return results of transaltion from threads +* +* @param translation translation of word found in dictionaries +* @param pattern a word which is being serch for in dictionaries +* @param user_data data passed to function +* @param error engine status information +*/ +void ws_mng_on_found_translation(gchar* translation, + gchar* pattern, + gpointer user_data, + EngineStatus error + ) +{ + g_debug("->%s", __FUNCTION__); + WSMngSearchAtom* search_atom = (WSMngSearchAtom*)user_data; + + /* we get already the first translation */ + if ((NULL != translation) && (NULL == search_atom->trans)) + { /* concatenate tags and searched word and translation */ + search_atom->trans = g_strconcat("", + pattern, + "", + translation, + "", + NULL + ); + } + else if (NULL != translation) + { /* if there was stored translation * + * copy stored translation to temporary variable*/ + gchar* tmp = g_strconcat(search_atom->trans, + "", + translation, + "", + NULL); + /* free memory used by stored old translation */ + gchar* loc_tmp = search_atom->trans; + search_atom->trans = tmp; + g_free(loc_tmp); + tmp = loc_tmp = NULL; + } + + g_debug("<-%s", __FUNCTION__); +} + + +/** +* \brief Function used to compare string. Used in sorting GArray object +* +*@param a first argument to compere +*@param b second argument to compere +*@return result of compare <0 if the second is greater than first 0 if the + strings are the same >0 if the first string is greater than second +*/ +gint ws_mng_compare_strings (gconstpointer a, gconstpointer b) +{ + gchar** str1 = (gchar**)(a); + gchar** str2 = (gchar**)(b); + + gchar* stra = g_utf8_strdown(str1[0], -1); + gchar* strb = g_utf8_strdown(str2[0], -1); + + gint result = g_utf8_collate(stra, strb); + + g_free(stra); + g_free(strb); + return result; +} + +void ws_remove_multiple_words(WSMngSearchAtom* user_data) +{ + WSMngSearchAtom* search = (WSMngSearchAtom*)user_data; + gint j = 0; + gint i = 0; + gint result = -1; + gint temp = 256; + gchar* tmp1 = NULL; + gchar* tmp2 = NULL; + + if (search->word_list->len < 256) + { + temp = search->word_list->len; + } + else + { + ws_dbus_notify(search->data->dbus_data, WS_DBUS_WORDS_LIST_FULL); + } + + for (i = 0; i < temp-1; i++) + { + tmp1 = g_utf8_casefold( + g_array_index(search->word_list,gchar*,i), + -1 + ); + for (j = i + 1; j < temp; j++) + { + /* search if there is a word on word list */ + tmp2 = g_utf8_casefold( + g_array_index(search->word_list,gchar*,j), + -1 + ); + result = g_utf8_collate(tmp1,tmp2); + g_free(tmp2); + tmp2 = NULL; + /* if there is a word on the word list + * remove that word */ + if (result == 0) + { + g_array_remove_index(search->word_list, j); + --j; + --temp; + if (search->word_list->len >= 256){ + temp = 256; + } + } + else { + /* there is no possiblity that further + * will be the same word, check next word */ + break; + } + } + g_free(tmp1); + tmp1 = NULL; + } +} + diff --git a/src/manager/src/ws_mng_threads_utils.c b/src/manager/src/ws_mng_threads_utils.c new file mode 100644 index 0000000..f8f1b44 --- /dev/null +++ b/src/manager/src/ws_mng_threads_utils.c @@ -0,0 +1,131 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#include + + +/* added by Dariusz Wiechecki + * trying to lock mutext and tells if it was locked */ +gboolean try_lock_was_locked(WSMngSearchData* data, gchar* fun) +{ + gboolean res = !g_static_mutex_trylock(data->action_working); + if (res) + { + g_debug("[M-action] %s - FAILED - locked already!", fun); + } + else + { + g_debug("[M-action] %s - SUCCESS - locked!", fun); + } + + return res; +} + +/* added by Dariusz Wiechecki + * check if recursive mutex is already locked + * must be call from critical section!!! */ +gboolean is_rec_locked(GStaticRecMutex* m) +{ + gboolean r = !g_static_rec_mutex_trylock(m); + if (FALSE == r) + { + g_static_rec_mutex_unlock(m); + g_debug("[M-stop] STOP mutex is UNLOCKED!"); + } + else + { + g_debug("[M-stop] STOP mutex is LOCKED"); + } + return r; +} + +/* added by Dariusz Wiechecki + * stop current thread if there is such a need - newer thread is waiting */ +void stop_if_needed(WSMngSearchAtom* data) +{ + static GStaticMutex _loc; + static GStaticMutex* loc = NULL; + if(NULL == loc && NULL == data) + { + g_debug("Initializing static mutex. function:%s\n",__FUNCTION__); + g_static_mutex_init (loc); + loc = &_loc; + return; + } + + WSMngSearchData* app_data = data->data; + /* critical section for calling is_rec_locked() function*/ + g_static_mutex_lock(loc); + if ( is_rec_locked(app_data->action_stop) ) + { + g_debug("[T-leaving] <---- Leaving thread (not finished).\n"); + ws_dbus_notify(app_data->dbus_data, WS_DBUS_WORDS_LIST_FINISHED); + ws_dbus_notify(app_data->dbus_data, WS_DBUS_TRANSLATION_FINISHED); + free_search_atom(data); + g_static_mutex_unlock(app_data->action_working); + g_static_mutex_unlock(loc); + g_thread_exit (NULL); + } + g_static_mutex_unlock(loc); +} + +void free_search_atom(WSMngSearchAtom* data) +{ + g_debug("[T-clear] Cleaning after thread\n"); + g_assert(NULL != data); + if (NULL != data->word) + { + g_free(data->word); + } + if (NULL != data->trans) + { + g_free(data->trans); + } + if (NULL != data->word_list) + { + /* free memory used by each word from word list */ + gint i = 0; + for (; i < data->word_list->len; i++) + { + g_free(g_array_index(data->word_list,gchar* ,i)); + } + /* free memory used by GArray */ + g_array_free(data->word_list, TRUE); + data->word_list = NULL; + } + g_free(data); +} + +WSMngSearchAtom *create_search_atom(WSMngSearchData* app_data, gchar* word) +{ + WSMngSearchAtom* search_data = NULL; + search_data = (WSMngSearchAtom*)g_try_malloc(sizeof(WSMngSearchAtom)); + if (NULL == search_data) + { + g_debug("[L-*] allocatting memmory for data failed!"); + return NULL; + } + /* get the word sended by dbus */ + search_data->word = g_strdup(word); + search_data->data = app_data; + search_data->word_list = NULL; + search_data->trans = NULL; + + return search_data; +} diff --git a/src/manager_copy/COPYING b/src/manager_copy/COPYING new file mode 100644 index 0000000..fb6319b --- /dev/null +++ b/src/manager_copy/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, 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 Lesser 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. + + GNU GENERAL PUBLIC LICENSE + 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. + + + Copyright (C) + + 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. + +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. + + , 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 Lesser General +Public License instead of this License. \ No newline at end of file diff --git a/src/manager_copy/bin/WhiteStorkManager b/src/manager_copy/bin/WhiteStorkManager new file mode 100755 index 0000000000000000000000000000000000000000..7eeb0540eb7837c57e0b03b4a332f383bd2c9b5f GIT binary patch literal 82553 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 literal 0 HcmV?d00001 diff --git a/src/manager_copy/include/pc-instances.h b/src/manager_copy/include/pc-instances.h new file mode 100644 index 0000000..5cf6b7d --- /dev/null +++ b/src/manager_copy/include/pc-instances.h @@ -0,0 +1,79 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#ifndef _PC_INSTANCES_H_ +#define _PC_INSTANCES_H_ +#ifdef __cplusplus +extern "C" { +#endif + +// stadards headers +#include +#include +#include +// headers with unix types/functions - only for timers and files operations +#include +#include +#include +#include +#include +#include + +//------------------------------------------------------------------------------ +/** \brief Get comandline by which process in /proc tree was invoked. + * + * @param process describes which process from /proc tree we want to check. It + * should be only concrete directory from /proc nothing else. e.g.: /proc/self, + * /proc/8321 etc. Something like /proc or /proc/self is not good. + * @return string containing comandline which has invoked process. If NULL there + * were some problems, possibly parameter were wrong or ther is no such + * a process. + */ +char* get_process_cmdline(char* process); + +//------------------------------------------------------------------------------ +/** \brief Cut from commandline only program file name. + * + * @param cmdline commandline which from which we want to remove options. + * @return string with only program file name, or NULL if there was any problem + */ +char* get_process_program_file(char* cmdline); + +//------------------------------------------------------------------------------ +/** \brief Get file name containing programm executing by current process. + * + * @return file name of program or NULL if there were some problems. + */ +char* get_current_process_program_file(); + +//------------------------------------------------------------------------------ +/** \brief Check if there is another instance of current programm. + * + * @return integer telling how many processes were initiated with the same + * program as curent process. If it is 1, it means there is no other procces. + * If > 1 there is another instance. + */ +int is_already_running_this_application(); + + + +#ifdef __cplusplus +} /* extern "C" { */ +#endif +#endif /* _PC_INSTANCES_H_ */ diff --git a/src/manager_copy/include/untar.h b/src/manager_copy/include/untar.h new file mode 100644 index 0000000..1eb8113 --- /dev/null +++ b/src/manager_copy/include/untar.h @@ -0,0 +1,16 @@ +#ifndef _WS_UNTAR +#define _WS_UNTAR + +#include +/* +Usage example: + +decompress_file ("comn_dictd04_wn.tar.bz2", "./"); + +The above example extracts a given archive, to the current directory +*/ + +gint decompress_file(gchar *in_file, gchar **out_path); + + +#endif /*_WS_UNTAR*/ diff --git a/src/manager_copy/include/ws_manager.h b/src/manager_copy/include/ws_manager.h new file mode 100644 index 0000000..800c73e --- /dev/null +++ b/src/manager_copy/include/ws_manager.h @@ -0,0 +1,182 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#ifndef _WS_MANAGER +#define _WS_MANAGER + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include + +#define GCONF_KEY "/apps/maemo/WhiteStork/Dictionaries" +#define GCONF_LIB_PATH "/apps/maemo/WhiteStork/Engines" + +#if SQLITE==0 + #define LIBRARY "/usr/lib/libsqlite.so.0" +#elif SQLITE==3 + #define LIBRARY "/usr/lib/libsqlite3.so.0" +#endif + +#define g_strlen(string) ( NULL == (string) ? 0 : strlen(string) ) + + +struct _WSMngSearchData; +typedef struct _WSMngSearchData WSMngSearchData; + +/** + * Creates new instance of WSMngSearchData structure + *@return new instance of WSMngSearchData structure + */ +WSMngSearchData* ws_manager_create(); + +/** +* \brief Function used to initialize D-BUS +* +*@param data structure stores variables which are need to comunicate by D-BUS. +*/ +void ws_mng_init_dbus (WSMngSearchData *data); + +/** +* \brief Function used to initialize manager +* +* Fuction loads from modules pointers to functions used to service searching +in dictionaries and stores them in WSMngSearchData structure +*@param data pointer to structure WSMngSearchData which stores variables needed +to service manager +*/ +void ws_mng_init (WSMngSearchData *data); + +/** +* \brief Function used to close dictionaries and modules +* +* @param data structure holds pointers to data which need to be freed +from memory +*/ +void ws_mng_close (WSMngSearchData *data); + +/** + * Function used to run and initialize main loop. + *@param serach_data structure which contains all data of program + *@return TRUE if successfully run main loop, FALSE otherwise + */ +gboolean ws_mng_start_main_loop(WSMngSearchData* serach_data); + +struct _WSMngSearchData +{ + GArray* dict; ///< pointer to GArray structure which stores pointers to fuction used to service dictionaries + GArray* modules; ///< pointer to GArray structure which stores pointers to fuction used to service modules loading + gchar* word; ///< word which will be used to search a dictionaries + pthread_t p_thread; ///< a thread in which we serching word list + pthread_t p_thread_trans; ///< a thread in which are searching for translation of word + WSDBusData* dbus_data; ///< a pointer DBUS data + GMainLoop* loop; ///< pointer to main loop + //GModule* library; ///< library used to load modules + GArray* word_list; ///< searched word list + gchar* trans; ///< searched translation + guint returned_results; ///< count of returned results + guint returned_trans_results; + gchar* last_search; ///< last searched word + gboolean search_in_history; ///< flag signalig when search in hisory is commieted + GArray* libraries; /// + +//------------------------------------------------------------------------------ +/** \brief Get comandline by which process in /proc tree was invoked. + * + * @param process describes which process from /proc tree we want to check. It + * should be only concrete directory from /proc nothing else. e.g.: /proc/self, + * /proc/8321 etc. Something like /proc or /proc/self is not good. + * @return string containing comandline which has invoked process. If NULL there + * were some problems, possibly parameter were wrong or ther is no such + * a process. + */ +char* get_process_cmdline(char* process) +{ + // build final filename to read + const char* postfix = "/cmdline"; + int arg_len = strlen(process); + char* tmp = (char*)malloc((size_t)(arg_len+9)); + tmp[arg_len+8] = '\0'; + sprintf(tmp,"%s%s",process,postfix); + //printf("Process to check: %s\n",tmp); + + // open file to read + int file = open(tmp, O_RDONLY); + free(tmp); tmp = 0; + if(-1 == file) + { + return (char*)0; + } + + int length = 512; + + // buffer for data from /proc/self/cmdline file + char* buffer = (char*)malloc(length + 1); + + // read file to buffer + int readed = read(file, buffer, length); + close(file); + if(readed == length) + { + free(buffer); + return (char*)0; + } + buffer[length] = '\0'; + + //printf("%s() returned finaly: %s\n",__FUNCTION__,buffer); + return buffer; +} +//------------------------------------------------------------------------------ +/** \brief Cut from commandline only program file name. + * + * @param cmdline commandline which from which we want to remove options. + * @return string with only program file name, or NULL if there was any problem + */ +char* get_process_program_file(char* cmdline) +{ + int start = 0; + int stop = 0; + // find first space in buffer (to remove optional options etc.) + while(cmdline[stop] && cmdline[stop] != ' ') + { + ++stop; + } + cmdline[stop] = '\0'; + + // find last "/" to remove directories + start = stop; + while((start>0) && (cmdline[start] != '/')) + { + --start; + } + if(cmdline[start] == '/') + { + ++start; + } + + // cut only needed fragment of buffer + if(start == stop) + { + return (char*)0; + } + + char* result = (char*)malloc(stop - start + 1); + memcpy(result, cmdline + start, stop - start + 1); + return result; +} +//------------------------------------------------------------------------------ +/** \brief Get file name containing program executing by current process. + * + * @return file name of program or NULL if there were some problems. + */ +char* get_current_process_program_file() +{ + char* cmd = get_process_cmdline("/proc/self"); + if(!cmd) + { + return (char*)0; + } + char* name = get_process_program_file(cmd); + free(cmd); cmd = 0; + + return name; +} +//------------------------------------------------------------------------------ +/** \brief Check if there is another instance of current programm. + * + * @return integer telling how many processes were initiated with the same + * program as curent process. If it is 1, it means there is no other procces. + * If > 1 there is another instance. + */ +int is_already_running_this_application() +{ + char* app = get_current_process_program_file(); + int count = 0; + + struct dirent* entry; + DIR* dir = opendir("/proc"); + struct stat st; + + char path[512]; + sprintf(path,"%s","/proc/"); + char* tmp = path + 6; + + while((entry = readdir(dir)) != NULL) + { + sprintf(tmp,"%s",entry->d_name); + lstat(path,&st); + + if(S_ISDIR(st.st_mode)) + { + char* cmd = get_process_cmdline(path); + if(!cmd) continue; + char* name = get_process_program_file(cmd); + free(cmd); cmd = 0; + if(!name) continue; + //printf("%s: next programm: %s\n",app,name); + + if(strcmp(app,name) == 0) + { + ++count; + } + + free(name); name = 0; + } + } + closedir(dir); dir = NULL; + free(app); app = 0; + return count; +} +//------------------------------------------------------------------------------ diff --git a/src/manager_copy/src/untar.c b/src/manager_copy/src/untar.c new file mode 100644 index 0000000..d0f1059 --- /dev/null +++ b/src/manager_copy/src/untar.c @@ -0,0 +1,229 @@ +#include +#include +#include +#include +#include +#include +//#include + +#define BLOCK_SIZE 512 +#define BUFFER_SIZE BLOCK_SIZE*32 +#define ASCII_NR(NR) (NR + 0x30) + +typedef struct _TarHeader +{ + gchar name[100]; + gchar mode[8]; + gchar uid[8]; + gchar gid[8]; + gchar size[12]; + gchar mtime[12]; + gchar chksum[8]; + gchar typeflag; + gchar linkname[100]; + gchar magic[6]; + gchar version[2]; + gchar uname[32]; + gchar gname[32]; + gchar devmajor[8]; + gchar devminor[8]; + gchar prefix[155]; + gchar padding[12]; + gchar *gnu_longname; + gchar *gnu_longlink; +} TarHeader; + +typedef enum _RecordType +{ + File = ASCII_NR (0), + ARCHLINK = ASCII_NR (1), + SYMLINK = ASCII_NR (2), + CHARDEV = ASCII_NR (3), + BLOCKDEV = ASCII_NR (4), + Dir = ASCII_NR (5), + FIFO = ASCII_NR (6), + RESERVED = ASCII_NR (7) +} RecordType; + +static gint unpack_file_contents(BZFILE *bz2_file, + TarHeader *header, + gchar *out_name); + + +static gint unpack_file_contents(BZFILE *bz2_file, + TarHeader *header, + gchar *out_name) +{ + gchar* buffer; + guint i; + FILE *file_out; + gulong length; + guint result; + gint bzerror; + + file_out = fopen(out_name, "w"); + + if (file_out == NULL) return -1; + + sscanf(header->size, "%12lo", &length); + g_debug("File size: %ld\n", length); + + for (i=0; i < (length / BLOCK_SIZE); ++i) + { + buffer = (gchar*) g_try_malloc (BLOCK_SIZE * sizeof(gchar)); + + result = BZ2_bzRead ( &bzerror, bz2_file, buffer, BLOCK_SIZE * + sizeof (gchar)); + + fwrite (buffer, BLOCK_SIZE * sizeof(gchar), 1, file_out); + g_free (buffer); + }; + + i = length % BLOCK_SIZE; + + if (i != 0) + { + buffer = (gchar*) g_try_malloc (BLOCK_SIZE * sizeof(gchar)); + + if (buffer == NULL) + { + g_debug("Memory not allocated"); + return -100; + }; + + result = BZ2_bzRead(&bzerror, bz2_file, buffer, + BLOCK_SIZE * sizeof(gchar)); + + if (bzerror == BZ_OK) + { + fwrite (buffer, i * sizeof(gchar), 1, file_out); + } + + else + { + g_debug("bzerror = %d", bzerror); + return -100; + }; + + g_free(buffer); + + }; + + fclose(file_out); + + return 0; +}; + +gint decompress_file (gchar *in_file, gchar **out_path) +{ + FILE *file; + BZFILE *bz2_file; + guint result; + TarHeader* header; + gint bzerror; + gchar* dest_dir = NULL; + header = (TarHeader*) g_try_malloc (BLOCK_SIZE * sizeof(gchar)); + + if (header == NULL) g_debug("\nCould not allocate memory\n"); + + file = fopen (in_file, "rb"); + + if (file != NULL) + + { + bz2_file = BZ2_bzReadOpen (&bzerror, file, 0, 0, NULL, 0); + + if ( bzerror != BZ_OK ) + { + BZ2_bzReadClose ( &bzerror, bz2_file ); + g_debug("There was an error while reading the compressed file\n"); + } + + bzerror = BZ_OK; + while (1) + { + + result = BZ2_bzRead ( &bzerror, bz2_file, header, + BLOCK_SIZE * sizeof (char)); + if ( bzerror == BZ_OK ) + { + if (strlen (header->name) == 0) + { + g_debug("\nFilename length is 0, exitting\n"); + break; + }; + + g_debug("Name: %s\n", header->name); + g_debug("Prefix: %s\n", header->prefix); + + + gchar *temp = g_strconcat (*out_path, + header->name, NULL); + g_debug("Temp path %s\n", temp); + switch (header->typeflag) + { + case File: + g_debug("File\n"); + unpack_file_contents (bz2_file, + header, temp); + break; + + case Dir: + + g_debug("Dir %s\n", temp); + if (mkdir (temp, S_IRUSR| + S_IWUSR|S_IXUSR) != 0) + { + g_debug("Couldn't create directory %s", + temp); + g_free(header); + BZ2_bzReadClose(&bzerror, + bz2_file); + fclose(file); + return -100; + }; + break; + + default: + g_debug("Only files and dirs can be unpacked"); + } + dest_dir = g_strdup(temp); + g_debug("dest_dir %s \n", dest_dir); + g_free (temp); + + } + + else if ( bzerror != BZ_STREAM_END ) + { + g_debug("\nBZ2 READ_CLOSE(stream end) %d\n", bzerror); + BZ2_bzReadClose ( &bzerror, bz2_file ); + break; + } + + else + { + g_debug("\nExitting, error nr %d\n", bzerror); + BZ2_bzReadClose ( &bzerror, bz2_file ); + break; + }; + + }; + + } + else + { + g_debug("There was an error while trying to read the archive file"); + g_free(header); header = NULL; + fclose(file); + return -100; + }; + if (dest_dir != NULL) + { + g_free(*out_path); *out_path = NULL; + *out_path = g_strdup(dest_dir); + g_free(dest_dir); dest_dir = NULL; + } + g_free(header); header = NULL; + fclose(file); + return 100; +}; diff --git a/src/manager_copy/src/whitestork.c b/src/manager_copy/src/whitestork.c new file mode 100644 index 0000000..121d76f --- /dev/null +++ b/src/manager_copy/src/whitestork.c @@ -0,0 +1,60 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ + +#include +#include +#include +#include +#include + +int main (gint argc, gchar** argv) +{ + /* initialize GType to be able to use GType and GObject */ + g_type_init(); + + /* initiliza GLib thread support... + * ...only if they are not initialized yet*/ + if (FALSE == g_thread_supported()) + { + g_thread_init(NULL); + } + + /* allocate memmory for application data */ + WSMngSearchData* search_data = ws_manager_create(); + if (NULL == search_data) + { + g_debug("Not enough memmory to allocate search_data!"); + return 1; + } + + /* init D-Bus and setup services */ + ws_mng_init_dbus(search_data); + + /* loading current configuration: engines, dictionaries etc. */ + ws_mng_init(search_data); + + /* module ready to work */ + ws_mng_start_main_loop(search_data); + + /* free any resources in use and close application */ + ws_mng_close(search_data); + return 0; +} + diff --git a/src/manager_copy/src/ws_manager.c b/src/manager_copy/src/ws_manager.c new file mode 100644 index 0000000..d87a423 --- /dev/null +++ b/src/manager_copy/src/ws_manager.c @@ -0,0 +1,1376 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#include + + +/* added by Dariusz Wiechecki + * trying to lock mutext and tells if it was locked */ +gboolean try_lock_was_locked(WSMngSearchData* data, gchar* fun) +{ + gboolean res = !g_static_mutex_trylock(data->action_working); + if (res) + { + g_debug("[M-action] %s - FAILED - locked already!", fun); + } + else + { + g_debug("[M-action] %s - SUCCESS - locked!", fun); + } + + return res; +} + +/* added by Dariusz Wiechecki + * check if recursive mutex is already locked + * must be call from critical section!!! */ +gboolean is_rec_locked(GStaticRecMutex* m) +{ + gboolean r = !g_static_rec_mutex_trylock(m); + if (FALSE == r) + { + g_static_rec_mutex_unlock(m); + g_debug("[M-stop] STOP mutex is UNLOCKED!"); + } + else + { + g_debug("[M-stop] STOP mutex is LOCKED"); + } + return r; +} + +/* added by Dariusz Wiechecki + * stop current thread if there is such a need - newer thread is waiting */ +void stop_if_needed(WSMngSearchData* data) +{ + static GStaticMutex _loc; + static GStaticMutex* loc = NULL; + if(NULL == loc && NULL == data) + { + g_debug("Initializing static mutex. function:%s\n",__FUNCTION__); + g_static_mutex_init (loc); + loc = &_loc; + return; + } + + /* critical section for calling is_rec_locked() function*/ + g_static_mutex_lock(loc); + if ( is_rec_locked(data->action_stop) ) + { + g_debug("~~~ <---- Leaving thread (not finished).\n"); + /* TODO clean after this thread!!!! */ + g_static_mutex_unlock(data->action_working); + g_static_mutex_unlock(loc); + g_thread_exit (NULL); + } + g_static_mutex_unlock(loc); +} + + +/** + * Public function, see ws_manager.h + */ +WSMngSearchData* ws_manager_create() +{ + g_debug("%s<->", __FUNCTION__); + WSMngSearchData* result = g_try_new(WSMngSearchData, 1); + + if (NULL == result) + { + g_debug("Not enough memory !"); + } + return result; +} + +/** + * Public function, see ws_manager.h + */ +gboolean ws_mng_start_main_loop(WSMngSearchData* search_data) +{ + g_debug("%s <-->", __FUNCTION__); + search_data->loop = g_main_loop_new (NULL, FALSE); + if (search_data->loop == NULL) + { + g_debug("Couldn't create new g_main_loop for Manager!"); + return FALSE; + } + g_main_loop_run (search_data->loop); + return TRUE; +} + +/** +* \brief Used to return results of transaltion from threads +* +* @param translation translation of word found in dictionaries +* @param pattern a word which is being serch for in dictionaries +* @param user_data data passed to function +* @param error engine status information +*/ +void ws_mng_on_found_translation(gchar* translation, + gchar* pattern, + gpointer user_data, + EngineStatus error + ) +{ + g_debug("->%s", __FUNCTION__); + WSMngSearchData *data = (WSMngSearchData *) user_data; + + /* if user want to stop searching */ + stop_if_needed(data); + + /* we get already the first translation */ + if ((NULL != translation) && (NULL == data->trans)) + { /* concatenate tags and searched word and translation */ + data->trans = g_strconcat("", + pattern, + "", + translation, + "", + NULL + ); + } + else if (NULL != translation) + { /* if there was stored translation * + * copy stored translation to temporary variable*/ + gchar* tmp = g_strconcat(data->trans, + "", + translation, + "", + NULL); + /* free memory used by stored old translation */ + gchar* loc_tmp = data->trans; + data->trans = tmp; + g_free(loc_tmp); + tmp = loc_tmp = NULL; + } + + /* if user want to stop searching */ + stop_if_needed(data); + + g_debug("<-%s", __FUNCTION__); +} +/* -------------------------------------------------------------------------- */ +/** + * Function used to send inforamtion about progress of caching XDXF file to UI + * @param progess how much file is cached + * @param user_data data needed to send information to UI + * @param error error messages + */ +void ws_mng_progress_bar(double progress, + gpointer user_data, + EngineStatus error + ) +{ + g_debug("<-> %s; progress=%f", __FUNCTION__, progress); + WSMngSearchData *data = (WSMngSearchData *) user_data; + /* return progress of caching to user interface */ + ws_dbus_server_update_progressbar(data->dbus_data, progress); + +} + +/** + *Function used to check if optimized flag in GConf is set + *@param dict path to dictionary file + *@return TRUE if dictionary is optimize, FALSE otherwise +*/ +gboolean ws_mng_if_optimized(gchar* dict) +{ + g_debug("->%s", __FUNCTION__); + + GConfClient* client; + gchar* path = NULL; + gboolean key_optimized = FALSE; + gboolean key_found = FALSE; + gint i = 0; + + client = gconf_client_get_default(); + GSList* list = gconf_client_all_dirs(client, GCONF_KEY, NULL); + for (i=0; i %s: reading parameters...", __FUNCTION__); + WSMngSearchData *search = (WSMngSearchData *) user_data; + osso_rpc_t* osso_data = NULL; + + /* ---> CRITICAL SECTION for this function */ + g_static_mutex_lock( search->thread_creation ); + + /* get the word passed by dbus */ + osso_data = &g_array_index (word, osso_rpc_t, 0); + search_t* tmp = (search_t*)g_try_malloc( sizeof(search_t) ); + tmp->word = g_strdup(osso_data->value.s); + tmp->data = search; + tmp->thread = NULL; + + g_debug("[L-word] creating GThread object..."); + tmp->thread = g_thread_create (ws_mng_search_word, tmp, TRUE, NULL); + g_debug("[L-word] GThread object created. Exiting from CREATOR."); + + g_static_mutex_unlock( search->thread_creation ); + /* <--- end of CRITICAL SECTION for this function */ + + g_debug("[L-word] <-%s", __FUNCTION__); +} +/* ------------------------------------------------------------------------ */ +void ws_remove_multiple_words(WSMngSearchData* user_data) +{ + WSMngSearchData* search = (WSMngSearchData*)user_data; + gint j = 0; + gint i = 0; + gint result = -1; + gint temp = 256; + gchar* tmp1 = NULL; + gchar* tmp2 = NULL; + + if (search->word_list->len < 256) + { + temp = search->word_list->len; + } + + for (i = 0; i < temp-1; i++) + { + tmp1 = g_utf8_casefold( + g_array_index(search->word_list,gchar*,i), + -1 + ); + for (j = i + 1; j < temp; j++) + { + /* search if there is a word on word list */ + tmp2 = g_utf8_casefold( + g_array_index(search->word_list,gchar*,j), + -1 + ); + result = g_utf8_collate(tmp1,tmp2); + g_free(tmp2); + tmp2 = NULL; + /* if there is a word on the word list + * remove that word */ + if (result == 0) + { + g_array_remove_index(search->word_list, j); + --j; + --temp; + if (search->word_list->len >= 256){ + temp = 256; + } + } + else { + /* there is no possiblity that further + * will be the same word, check next word */ + break; + } + } + g_free(tmp1); + tmp1 = NULL; + } +} +/* ------------------------------------------------------------------------ */ +/** +* \brief Function used to compare string. Used in sorting GArray object +* +*@param a first argument to compere +*@param b second argument to compere +*@return result of compare <0 if the second is greater than first 0 if the + strings are the same >0 if the first string is greater than second +*/ +gint ws_mng_compare_strings (gconstpointer a, gconstpointer b) +{ + gchar** str1 = (gchar**)(a); + gchar** str2 = (gchar**)(b); + + gchar* stra = g_utf8_strdown(str1[0], -1); + gchar* strb = g_utf8_strdown(str2[0], -1); + + gint result = g_utf8_collate(stra, strb); + + g_free(stra); + g_free(strb); + return result; +} +/* ------------------------------------------------------------------------ */ +/** +* \brief Function used to run search for word engine in threads +* +* @param data required data for search word event +* @return gpointer return value +*/ +gpointer ws_mng_search_word (gpointer user_data) +{ + g_debug("[T-word] %s: Entering thread...", __FUNCTION__); + search_t* data = (search_t*)user_data; + WSMngSearchData *search = data->data; + + /* enter into CRITICAL SECTION */ + if (try_lock_was_locked(search,(gchar*)__FUNCTION__)) + { + g_printf("[T-word] STOP mutex is locked! Aborting others!"); + g_static_rec_mutex_lock(search->action_stop); + g_static_mutex_lock(search->action_working); + } + g_static_rec_mutex_unlock(search->action_stop); + + /* if another thread was run after this one - exit */ + stop_if_needed(search); + + g_debug("[T-word] %s - from now this thread is \'singleton\' ", + __FUNCTION__ + ); + + /* creating new GArray for word list */ + search->word_list = g_array_new(TRUE, TRUE, sizeof(gchar*)); + + g_debug("[T-word] %s - start searching... ",__FUNCTION__); + if (search->bookmark_mode) + { /* search only in user bookmarks */ + dict_eng_search_word_list(search->bookmark, + data->word); + } + else + { /* search for word in each dictionary */ + gint i = 0; + for (i = 0; i < search->dict->len; i++) + { + if (NULL == g_array_index(search->dict, Engine *, i)) + { + continue; + } + + stop_if_needed(search); + Engine* dict = g_array_index(search->dict,Engine *,i); + dict_eng_search_word_list(dict, data->word); + } + } + g_debug("[T-word] %s - searching finished.",__FUNCTION__); + + /* if another thread was run after this one - exit */ + stop_if_needed(search); + + /* sort and cleaning words list - only if there were more than one + * dictionary loaded */ + if ((FALSE == search->bookmark_mode) || (1 < search->dict->len)) + { + g_array_sort(search->word_list, ws_mng_compare_strings); + ws_remove_multiple_words(search); + } + + /* if another thread was run after this one - exit */ + stop_if_needed(search); + + ws_dbus_server_return_words(search->dbus_data, search->word_list); + + /* free memory used by each word from word list */ + gint i = 0; + for (; i < search->word_list->len; i++) + { + g_free(g_array_index(search->word_list,gchar* ,i)); + } + + /* free memory used by GArray */ + g_array_free(search->word_list, TRUE); + search->word_list = NULL; + + g_free(data->word); + g_free(data); + g_debug("[T-word] %s - leaving thread!", __FUNCTION__); + g_static_mutex_unlock(search->action_working); + return NULL; +} + +/** +* \brief Used to return results of found word from threads +* +* @param list word list found in dictionaries +* @param pattern a word which is being search for in dictionaries +* @param user_data data passed to function +* @param error engine status information +*/ +void ws_mng_on_found_word(GArray* list, + gchar* pattern, + gpointer user_data, + EngineStatus error) +{ + g_debug("[T-word-ret]-> %s", __FUNCTION__); + + WSMngSearchData *data = (WSMngSearchData *) user_data; + static gint i = 0; + for (i = 0; i < list->len; i++) + { + /* copy word found by search engine */ + gchar* new_word = g_strdup(g_array_index(list, gchar*, i)); + g_array_append_val(data->word_list, new_word); + + } + + g_debug("[T-word-ret]<- %s", __FUNCTION__); +} + + + +/** +* \brief Called when find translation event occurs +* +* @param word word to search +* @param error error messages +* @param user_data user data passed to function +*/ +void ws_mng_on_search_translation (GError *error, GArray *word, + gpointer user_data) +{ + g_debug("[L-tran] ->%s", __FUNCTION__); + + WSMngSearchData *data = (WSMngSearchData *) user_data; + + /* ---> CRITICAL SECTION for this function */ + g_static_mutex_lock(data->thread_creation); + + osso_rpc_t *osso_data; + /* get the data sended by dbus */ + osso_data = &g_array_index (word, osso_rpc_t, 0); + /* get the word sended by dbus */ + data->word = g_strdup(osso_data->value.s); + + g_debug("[L-tran] creating GThread object..."); + g_thread_create (ws_mng_search_translation, data, TRUE, NULL); + g_debug("[L-tran] GThread object created. Exiting from CREATOR."); + + + g_static_mutex_unlock(data->thread_creation); + /* <--- end of CRITICAL SECTION for this function */ + + g_debug("[L-tran] <-%s", __FUNCTION__); +} + +/* -------------------------------------------------------------------------- */ +/** +* \brief Function used to run search for transaltion of word engine in threads +* +* @param data required data for search translation +* @return gpointer return value +*/ +gpointer ws_mng_search_translation (gpointer data) +{ + g_debug("[T-tran] %s: Entering thread...", __FUNCTION__); + WSMngSearchData *search = (WSMngSearchData *) data; + + /* ---> CRITICAL SECTION for this function */ + if (try_lock_was_locked(search,(gchar*)__FUNCTION__)) + { + g_printf("[T-tran] STOP mutex is locked! Aborting others!"); + g_static_rec_mutex_lock(search->action_stop); + g_static_mutex_lock(search->action_working); + } + g_static_rec_mutex_unlock(search->action_stop); + /* if another thread was run after this one - exit */ + stop_if_needed(search); + + g_debug("[T-tran] %s - from now this thread is \'singleton\' ", + __FUNCTION__ + ); + + /* run search for translation for every dictionary */ + if (search->bookmark_mode) + { + dict_eng_search_word_translation(search->bookmark, + search->word); + } + else + { + gint i; + for (i = 0; i < search->dict->len; i++) + { + stop_if_needed(search); + if (NULL == g_array_index(search->dict, Engine*, i) ) + { + continue; + } + dict_eng_search_word_translation( + g_array_index(search->dict, Engine*, i), + search->word + ); + } + } + g_debug("[T-tran] %s - searching finished.",__FUNCTION__); + + /* if another thread was run after this one - exit */ + stop_if_needed(search); + + /* send translation to gui */ + ws_dbus_server_return_translations(search->dbus_data, search->trans); + + g_free(search->trans); + search->trans = NULL; + + g_debug("[T-word] %s - leaving thread!", __FUNCTION__); + g_static_mutex_unlock(search->action_working); + return NULL; +} + + +/** + *Function used to load dictionaries engines + *@param dict_directory path to dictionaries + *@param data structure which contains all data of program +*/ +void ws_mng_load_dict(GArray* dict_directory, WSMngSearchData* data) +{ + + gint i = 0; + gint j = 0; + Engine* xdxf = NULL; + g_debug("->%s", __FUNCTION__); + for (i =0; ilen; i++) + { + gchar* current_directory = strdup(g_array_index(dict_directory, + gchar*, + i) + ); + for (j=0; jmodules->len; j++) + { + if (dict_eng_module_check(g_array_index(data->modules, + EngineModule, + j), + current_directory) == TRUE) + { + if(ws_mng_if_optimized(current_directory)) + { + xdxf = dict_eng_module_create_ext( + g_array_index(data->modules, + EngineModule, + j), + current_directory, + ENGINE_CREATE, + ws_mng_progress_bar, + data, + 0.02); //create engine module + } + else + { + xdxf = dict_eng_module_create_ext( + g_array_index(data->modules, + EngineModule, + j), + current_directory, + ENGINE_NO, + ws_mng_progress_bar, + data, + 0.02); //create engine module + } + //set callback for return words list function + dict_eng_set_callback(xdxf, + ENGINE_WORD_LIST_SIGNAL, + ws_mng_on_found_word, + data); + //set callback for return translation + dict_eng_set_callback(xdxf, + ENGINE_WORD_TRANSLATION_SIGNAL, + ws_mng_on_found_translation, + data); + //adding newly created engine to Garray + g_array_append_val (data->dict, xdxf); + g_free(current_directory); + } + } + } + g_debug("<-%s", __FUNCTION__); +} + +/** + *Function used to get the dictionaries location read fron GConf + *@return path to dictionaries location + */ +GArray* ws_mng_read_gconf() +{ + //g_type_init(); + g_debug("--%s", __FUNCTION__); + GConfClient* client = NULL; + GArray* path_to_dir = g_array_new(TRUE, TRUE, sizeof(gchar *)); + gchar* path = NULL; + //gchar* key_value = NULL; + gboolean key_active = FALSE; + gint i = 0; + + client = gconf_client_get_default(); + GSList* list = gconf_client_all_dirs(client, GCONF_KEY, NULL); + for (i=0; i%s", __FUNCTION__); + osso_rpc_t osss_data; + osss_data = g_array_index (signal, osso_rpc_t, 0); + WSMngSearchData *data = (WSMngSearchData *) user_data; + gint i = 0; + switch(osss_data.value.i) + { + case WS_DBUS_INFO_TERMINATE: + + g_main_loop_quit (data->loop); + break; + case WS_DBUS_INFO_STOP_SEARCH: + /* added by Dariusz Wiechecki + * canceling GLib Threads */ + if (try_lock_was_locked(data,(gchar*)__FUNCTION__)) + { + g_printf("~~~STOP ACTION! %s\n",__FUNCTION__); + g_static_rec_mutex_lock(data->action_stop); + g_static_mutex_lock(data->action_working); + } + g_static_rec_mutex_unlock(data->action_stop); + g_static_mutex_unlock(data->action_working); + break; + + case WS_DBUS_INFO_CONFIG_CHANGED: + ws_dbus_notify(data->dbus_data, WS_DBUS_INFO_CACHING); + + for (i=0; idict->len; i++) + { + if (g_array_index(data->dict, Engine*,i) != NULL) + { + dict_eng_destroy( + g_array_index( + data->dict, Engine*,i + ) + ); + } + } + g_array_free(data->dict, TRUE); + + data->dict = g_array_new (TRUE, TRUE, sizeof(Engine*));; + //paths to directories + GArray* dir_array = ws_mng_read_gconf(); + //fill the table again with new dicnioraries + ws_mng_load_dict(dir_array, data); + //if there is no dictionary selected + // signal this fact to gui + if (data->dict->len <= 0) + { + ws_dbus_notify(data->dbus_data, + WS_DBUS_INFO_CACHING_FINISHED); + ws_dbus_notify(data->dbus_data, + WS_DBUS_ERROR_FILE_NOT_FOUND); + }else + { + data->returned_results = data->dict->len; + data->returned_trans_results = data->dict->len; + //if there was typed word search for word list + if (data->last_search != NULL) + { +// for (i=0; iword_list->len; i++) +// { +// g_free( +// g_array_index(data->word_list, +// gchar* , +// i)); +// } +// //free the old words list +// g_array_free(data->word_list, TRUE); + + data->word_list = g_array_new(TRUE, TRUE, + sizeof(gchar*));//creating new word list + + g_free(data->word); data->word = NULL; + data->word = g_strdup(data->last_search); + //create searching thread + /*pthread_create (&data->p_thread, + NULL, + ws_mng_search_word, + data);*/ + } + //signal end of dictionary load to gui + ws_dbus_notify(data->dbus_data, + WS_DBUS_INFO_CACHING_FINISHED); + } + //free memory + for (i=0; ilen; i++) + { + g_free(g_array_index(dir_array, gchar*, i)); + } + g_array_free(dir_array, TRUE); + break; + case WS_DBUS_BOOKMARK_MODE_ON: + data->bookmark_mode = TRUE; + break; + + case WS_DBUS_BOOKMARK_MODE_OFF: + data->bookmark_mode = FALSE; + break; + + } + g_debug("<-%s", __FUNCTION__); +} +/** + *Function used to add bookmarks + *@param error error messages + *@param param word and translation of word to adding + *@param user_data structure holding nedded parameters + */ +void ws_mng_add_bookmark(GError *error, GArray* param, + gpointer user_data) +{ + g_debug("->%s", __FUNCTION__); + + WSMngSearchData* data = (WSMngSearchData *) user_data; + osso_rpc_t* osso_data = NULL; + osso_rpc_t* osso_data_trans = NULL; + gchar* word = NULL; + gchar* translation = NULL; + //get the word passed by dbus + if (data->bookmark != NULL) + { + //g_debug("adding bookmarks...%p locataion", data->bookmark); + osso_data = &g_array_index (param, osso_rpc_t, 0); + word = g_strdup(osso_data->value.s); + osso_data_trans = &g_array_index (param, osso_rpc_t, 1); + translation = g_strdup(osso_data_trans->value.s); + //do not free translation and word + gboolean is_added = dict_eng_add_word(data->bookmark, + word, translation); + if (is_added == TRUE) + { + ws_dbus_notify(data->dbus_data, + WS_DBUS_BOOKMARKS_ADDED_OK); + } + else + { + ws_dbus_notify(data->dbus_data, + WS_DBUS_BOOKMARKS_ADDED_FAIL); + } + osso_rpc_free_val(osso_data); + g_free(translation); + g_free(word); + } + else + { + ws_dbus_notify(data->dbus_data, + WS_DBUS_BOOKMARKS_ADDED_FAIL); + g_debug("-> %s - there is no bookmark engine!\n", __FUNCTION__); + } + g_debug("<-%s", __FUNCTION__); +} + +/** + *Function used to remove bookmarks + *@param error error messages + *@param param word and translation of word to adding + *@param user_data structure holding nedded parameters + */ +void ws_mng_remove_bookmark(GError *error, GArray* param, + gpointer user_data) +{ + g_debug("->%s", __FUNCTION__); + + WSMngSearchData* data = (WSMngSearchData *) user_data; + osso_rpc_t* osso_data = NULL; + gchar* word = NULL; + //get the word passed by dbus + if (data->bookmark != NULL) + { + g_debug("removing bookmarks..."); + osso_data = &g_array_index(param, osso_rpc_t, 0); + word = g_strdup(osso_data->value.s); + + gboolean is_remove = dict_eng_remove_word(data->bookmark, word); + if (is_remove == TRUE) + { + ws_dbus_notify(data->dbus_data, + WS_DBUS_BOOKMARKS_REMOVED_OK); + } + else + { + ws_dbus_notify(data->dbus_data, + WS_DBUS_BOOKMARKS_REMOVED_FAIL); + } + + osso_rpc_free_val(osso_data); + } + else + { + ws_dbus_notify(data->dbus_data, + WS_DBUS_BOOKMARKS_ADDED_FAIL); + g_debug("-> %s - there is no bookmark engine!\n", __FUNCTION__); + } + g_debug("<-%s", __FUNCTION__); +} + +/** + *Public function, see ws_manager.h + */ +void ws_mng_init_dbus (WSMngSearchData *data) +{ + g_debug("->%s", __FUNCTION__); + + /* create data structure needed to comunicate with dbus wrapper */ + data->dbus_data = ws_dbus_create ("WhiteStorkManager", "v1.0"); + + /* set data used to comunicate with gui */ + ws_dbus_config(data->dbus_data, + WS_DBUS_CONFIG_SERVICE, + "org.maemo.WhiteStorkManager"); + ws_dbus_config(data->dbus_data, + WS_DBUS_CONFIG_OBJECT, + "/org/maemo/WhiteStorkManager"); + ws_dbus_config(data->dbus_data, + WS_DBUS_CONFIG_IFACE, + "org.maemo.WhiteStorkManager"); + ws_dbus_config(data->dbus_data, + WS_DBUS_CONFIG_REMOTE_SERVICE, + "org.maemo.WhiteStorkGui"); + ws_dbus_config(data->dbus_data, + WS_DBUS_CONFIG_REMOTE_OBJECT, + "/org/maemo/WhiteStorkGui"); + ws_dbus_config(data->dbus_data, + WS_DBUS_CONFIG_REMOTE_IFACE, + "org.maemo.WhiteStorkGui"); + + ws_dbus_connect(data->dbus_data); + + /* set callback for find word signal */ + ws_dbus_set_cb(data->dbus_data, + "find_word", + ws_mng_on_search_word, + data); + + /* set callback for find translation signal */ + ws_dbus_set_cb(data->dbus_data, + "find_translation", + ws_mng_on_search_translation, + data); + + /* set callback for close program signal */ + ws_dbus_set_cb(data->dbus_data, + "signal", + ws_mng_signal_handling, + data); + + /* set callback for add bookmarks signal */ + ws_dbus_set_cb(data->dbus_data, + "add_bookmark", + ws_mng_add_bookmark, + data); + + /* set callback for remove bookmarks signal */ + ws_dbus_set_cb(data->dbus_data, + "remove_bookmark", + ws_mng_remove_bookmark, + data); + + /* set callback for extracting dictionary */ + ws_dbus_set_cb(data->dbus_data, + "extract_dictionary", + ws_mng_extract_dictionary, + data); + + g_debug("<-%s", __FUNCTION__); +} + +/** + *Function used to get plugins location read from GConf + *@return libraries location + */ +GArray* ws_mng_get_engines_location() +{ + + //g_type_init(); + g_debug("->%s", __FUNCTION__); + GConfClient* client = NULL; + GArray* path_to_dir = g_array_new(TRUE, TRUE, sizeof(gchar *)); + gchar* path = NULL; + gint i = 0; + client = gconf_client_get_default(); + GSList* list = gconf_client_all_dirs(client, GCONF_LIB_PATH, NULL); + for (i=0; i%s", __FUNCTION__); + //g_type_init(); + GConfClient* client = NULL; + gchar* path = NULL; + guint i = 0; + client = gconf_client_get_default(); + GSList* list = gconf_client_all_dirs(client, GCONF_KEY, NULL); + for (i=0; i%s", __FUNCTION__); + guint i = 0; + data->bookmark = NULL; + gchar* current_directory = ws_mng_get_boomark_location(); + if (current_directory != NULL) + { + #ifdef SQLITE + if (g_file_test(LIBRARY, G_FILE_TEST_EXISTS)) + { + #endif + for (i=0; imodules->len; i++) + { + if (dict_eng_module_check( + g_array_index(data->modules, EngineModule, i), + current_directory) == TRUE) + { + data->bookmark = + dict_eng_module_create_ext( + g_array_index(data->modules, + EngineModule, + i), + current_directory, + ENGINE_CREATE, + ws_mng_progress_bar, + data, + 0.02); + dict_eng_set_callback(data->bookmark, + ENGINE_WORD_LIST_SIGNAL, + ws_mng_on_found_word, + data); + //set callback for return translation + dict_eng_set_callback(data->bookmark, + ENGINE_WORD_TRANSLATION_SIGNAL, + ws_mng_on_found_translation, + data); + + break; + } + } + + #ifdef SQLITE + } + #endif + g_free(current_directory); + } + g_debug("<-%s", __FUNCTION__); +} + +/** + *Public fuction, see ws_manager.h + */ +void ws_mng_init (WSMngSearchData *data) +{ + g_debug("->%s", __FUNCTION__); + data->dict = g_array_new(TRUE, TRUE, sizeof(Engine *)); + data->modules = g_array_new(TRUE, TRUE, sizeof(EngineModule)); + data->libraries = g_array_new(TRUE, TRUE, sizeof(GModule*)); + data->word_list = NULL; + data->last_search = NULL; + data->trans = NULL; + data->search_in_history = FALSE; + data->word = NULL; + data->bookmark = NULL; + data->bookmark_mode = FALSE; + /* added by Dariusz Wiechecki + * mutex initialization */ + data->action_working = (GStaticMutex*)g_try_malloc(sizeof(GStaticMutex)); + data->thread_creation = (GStaticMutex*)g_try_malloc(sizeof(GStaticMutex)); + data->action_stop = (GStaticRecMutex*)g_try_malloc(sizeof(GStaticRecMutex)); + g_assert(NULL != (data->action_working) ); + g_assert(NULL != (data->action_stop) ); + g_static_mutex_init (data->action_working); + g_static_mutex_init (data->thread_creation); + g_static_rec_mutex_init (data->action_stop); + /* initialize static stop_if_needed function mutex*/ + stop_if_needed (NULL); + /* initialize GThread structure */ + //data->action_thread = NULL; + + #ifdef SQLITE + if (g_file_test(LIBRARY, + G_FILE_TEST_EXISTS) == FALSE) + { + ws_dbus_notify(data->dbus_data, WS_DBUS_LOAD_BOOKMARK_FAILED); + } + #endif + + GArray* dict_directory = ws_mng_read_gconf(); //paths to dictionaries + gint i = 0; + + data->returned_results = dict_directory->len; + data->returned_trans_results = dict_directory->len; + data->library_path = ws_mng_get_engines_location(); + //load the engine function + for (i = 0; i < data->library_path->len; i++) + { + gchar* path= g_array_index(data->library_path, gchar*, i); + GModule* library = g_module_open(path, G_MODULE_BIND_LAZY); + g_array_append_val(data->libraries, library); + g_debug("%p library pinter %d iter", library, i); + //g_free(path); + } + //data->library = g_module_open(library_to_path, G_MODULE_BIND_LAZY); + + for (i=0; ilibraries->len; i++) + { + getting_additional get_functions = NULL; + //get_functions = NULL; + //data->library + g_debug("%p", g_array_index(data->libraries, GModule*, i)); + g_module_symbol(g_array_index(data->libraries, GModule*, i), + "engine_global_functions", + (gpointer)&get_functions); + g_debug("%d %p", i, &get_functions); + if (get_functions == NULL) //check if function was loaded + { + ws_dbus_notify(data->dbus_data, + WS_DBUS_ERROR_ENGINE_NOT_FOUND); + for (i=0; ilen; i++) + { + g_free(g_array_index(dict_directory, gchar*, i)); + } + g_array_free(dict_directory, TRUE); + ws_mng_close(data); + exit(0); //exit program + } + EngineModule module = get_functions(); + //tmp = (EngineModule*) g_memdup(&module, sizeof(EngineModule)); + //module = (EngineModule**) &tmp; + g_array_append_val(data->modules, module); + + } + + ws_mng_load_bookmark(data); + if (dict_directory->len > 0) + { + ws_dbus_notify(data->dbus_data, WS_DBUS_INFO_CACHING); + + ws_mng_load_dict(dict_directory, data); + guint i = 0; + g_debug("Trace bookmark engine %p", data->bookmark); + for (i=0; idict->len; i++) + { + g_debug("dict engines at %p", + g_array_index(data->dict, Engine*, i)); + } + ws_dbus_notify(data->dbus_data, + WS_DBUS_INFO_CACHING_FINISHED); + } + else + { + ws_dbus_notify(data->dbus_data, + WS_DBUS_ERROR_FILE_NOT_FOUND); + } + for (i=0; ilen; i++) + { + g_free(g_array_index(dict_directory, gchar*, i)); + } + g_array_free(dict_directory, TRUE); + g_debug("<-%s", __FUNCTION__); +} + +/** + *Public function, see ws_manager.h + */ +void ws_mng_close (WSMngSearchData *data) +{ + int i = 0; + g_debug("->%s", __FUNCTION__); + + ws_dbus_destroy (data->dbus_data); // deinitialization of dbus + if (data->bookmark != NULL) + { + dict_eng_destroy(data->bookmark); + } + + for (i = 0; i < data->dict->len; i++) + { + //free memory taken by engine + dict_eng_destroy(g_array_index (data->dict, Engine*,i)); + } + g_array_free(data->dict, TRUE); + + /*for (i=0; iword_list->len; i++) + { + g_free(g_array_index(data->word_list, gchar*, i)); + } + + g_array_free(data->word_list, TRUE);*/ + + //free memory used by modules + //g_array_free(data->modules, TRUE); + //free memory taken by dictionaries + g_free(data->last_search); + + g_free(data->loop); + + g_free(data->thread_creation); + g_free(data->action_working); + g_free(data->action_stop); + /*if (data->word != NULL) g_free(data->word);*/ + + //if (data->trans != NULL) g_free(data->trans); + + for (i=0; ilibrary_path->len; i++) + { + g_free(g_array_index(data->library_path, gchar*, i)); + } + g_array_free(data->library_path, TRUE); + + g_array_free(data->modules, TRUE); data->modules = NULL; + + for (i=0; i< data->libraries->len; i++) + { + if (g_array_index(data->libraries, GModule*, i) != NULL) + { + //close library + g_module_close(g_array_index(data->libraries, + GModule*, i)); + } + + } + + g_array_free(data->libraries, TRUE); + + g_free(data); + + g_debug("<-%s", __FUNCTION__); +} + +void ws_mng_extract_dictionary(GError *error, + GArray* param, + gpointer user_data) +{ + g_debug("->%s", __FUNCTION__); + WSMngSearchData *data = (WSMngSearchData *) user_data; + osso_rpc_t *osso_data; + //get the data sended by dbus + osso_data = &g_array_index (param, osso_rpc_t, 0); + //get the path sended by dbus + gchar* path = g_strdup(osso_data->value.s); + gint result = -1; + + gchar* dest = NULL; + if (path != NULL) + { + gint count = 0; + gchar** tmp = g_strsplit(path, + "/", + 0); + while(tmp[count++] != NULL); + dest = g_strndup(path, g_strlen(path)- g_strlen(tmp[count -2])); + g_strfreev(tmp); + } + if (dest != NULL) + { ws_dbus_notify(data->dbus_data, WS_DBUS_EXTRACT_FILE); + result = decompress_file(path, &dest); + ws_dbus_notify(data->dbus_data, WS_DBUS_EXTRACT_FILE_FINISHED); + } + + if (result > 0) + { + ws_dbus_server_return_extracted_dict(data->dbus_data, dest); + } + else + { + dest = ""; + ws_dbus_server_return_extracted_dict(data->dbus_data, dest); + } + + g_free(path); + g_debug("<-%s", __FUNCTION__); +} + diff --git a/src/plugins/stardict/COPYING b/src/plugins/stardict/COPYING new file mode 100755 index 0000000..fb6319b --- /dev/null +++ b/src/plugins/stardict/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, 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 Lesser 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. + + GNU GENERAL PUBLIC LICENSE + 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. + + + Copyright (C) + + 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. + +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. + + , 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 Lesser General +Public License instead of this License. \ No newline at end of file diff --git a/src/plugins/stardict/Makefile b/src/plugins/stardict/Makefile new file mode 100755 index 0000000..092074a --- /dev/null +++ b/src/plugins/stardict/Makefile @@ -0,0 +1,56 @@ +COMPILER = gcc +DEBUG = -Wall -g +INCLUDE = ./include +ENGINE_INCLUDE = ../../../include +LIBS = `pkg-config --libs glib-2.0 gmodule-2.0 gnome-vfs-2.0` -lz +FLAGS = `pkg-config --cflags glib-2.0 gmodule-2.0 gnome-vfs-2.0` -I${INCLUDE} -I${ENGINE_INCLUDE} +SOURCES = ./src +MAIN_BINARIES = ../../../bin +BINARIES = ./bin +PRECOMPILED = ./precompiled + +first-target: library + +build: library + +all: clean library test check + +clean: + @-rm -f ${BINARIES}/* + @-rm -f ${SOURCES}/*~ + @-rm -f *~ + @-rm -f ${INCLUDE}/*~ + @-rm -f ${SOURCES}/engine_stardict.so + @echo -e -n "Project 'StarDictEngine' directories has been cleaned.\n" + +test: ${SOURCES}/test.c + @${COMPILER} ${LIBS} ${FLAGS} ${DEBUG} -o ${BINARIES}/test ${SOURCES}/test.c + @echo -e -n "Building test program for 'StarDictEngine' finished.\n" + +check: test + @run-standalone.sh ${BINARIES}/test + + +library: ${BINARIES}/engine_stardict.o + @${COMPILER} ${DEBUG} -shared -fPIC ${FLAGS} ${LIBS} ${BINARIES}/engine_stardict.o \ + ${PRECOMPILED}/`arch`/*.o -o ${BINARIES}/engine_stardict.so + @cp ${BINARIES}/engine_stardict.so ${MAIN_BINARIES} + @echo -e -n "'StarDictEngine' build finished.\n" + +${BINARIES}/engine_stardict.o: ${SOURCES}/engine_stardict.c + @${COMPILER} ${DEBUG} ${FLAGS} -c -fPIC ${SOURCES}/engine_stardict.c -o ${BINARIES}/engine_stardict.o + + +final: clean + @${COMPILER} -DNOLOGS -Wall -O3 ${FLAGS} -c -fPIC ${SOURCES}/engine_stardict.c -o ${BINARIES}/engine_stardict.o + @${COMPILER} -DNOLOGS -Wall -g -shared -fPIC ${FLAGS} ${LIBS} ${BINARIES}/engine_stardict.o \ + ${SOURCES}/`arch`/*.o -o ${BINARIES}/engine_stardict.so + @cp ${BINARIES}/engine_stardict.so ../bin + @echo -e -n "'StarDictEngine' build finished. (Final version - optimized)\n" + + + + + + + \ No newline at end of file diff --git a/src/plugins/stardict/doc/DICTFILE_FORMAT b/src/plugins/stardict/doc/DICTFILE_FORMAT new file mode 100755 index 0000000..17f84fc --- /dev/null +++ b/src/plugins/stardict/doc/DICTFILE_FORMAT @@ -0,0 +1,465 @@ +Format for StarDict dictionary files +------------------------------------ + +StarDict homepage: http://stardict.sourceforge.net + +{0}. Number and Byte-order Conventions +When you record the numbers that identify sizes, offsets, etc., you +should use 32-bit numbers, such as you might represent with a glong. + +In order to make StarDict work on different platforms, these numbers +must be in network byte order. You can ensure the correct byte order +by using the g_htonl() function when creating dictionary files. +Conversely, you should use g_ntohl() when reading dictionary files. + +Strings should be encoded in UTF-8. + + +{1}. Files +Every dictionary consists of these files: +(1). somedict.ifo +(2). somedict.idx or somedict.idx.gz +(3). somedict.dict or somedict.dict.dz +(4). somedict.syn (optional) + +You can use gzip -9 to compress the .idx file. If the .idx file are not +compressed, the loading can be fast and save memory when using, compress it +will make the .idx file load into memory and make the quering become faster +when using. + +You can use dictzip to compress the .dict file. +"dictzip" uses the same compression algorithm and file format as does gzip, +but provides a table that can be used to randomly access compressed blocks +in the file. The use of 50-64kB blocks for compression typically degrades +compression by less than 10%, while maintaining acceptable random access +capabilities for all data in the file. As an added benefit, files +compressed with dictzip can be decompressed with gunzip. +For more information about dictzip, refer to DICT project, please see: +http://www.dict.org + +When you create a dictionary, you should use .idx and .dict.dz in normal +case. + +Stardict will search for the .ifo file, then open the .idx or +.idx.gz file and the .dict.dz or .dict file which is in the same directory and +has the same base name. + + + +{2}. The ".ifo" file's format. +The .ifo file has the following format: + +StarDict's dict ifo file +version=2.4.2 +[options] + +Note that the current "version" string must be "2.4.2". If it's not, +then StarDict will refuse to read the file. + +[options] +--------- +In the example above, [options] expands to any of the following lines +specifying information about the dictionary. Each option is a keyword +followed by an equal sign, then the value of that option, then a +newline. The options may be appear in any order. + +Note that the dictionary must have at least a bookname, a wordcount and a +idxfilesize, or the load will fail. All other information is optional. All +strings should be encoded in UTF-8. + +Available options: + +bookname= // required +wordcount= // required +synwordcount= // required if ".syn" file exists. +idxfilesize= // required +author= +email= +website= +description= +date= +sametypesequence= // very important. + + +wordcount is the count of word entries in .idx file, it must be right. + +idxfilesize is the size(in bytes) of the .idx file, even the .idx is compressed +to a .idx.gz file, this entry must record the original .idx file's size, and it +must be right too. The .gz file don't contain its original size information, +but knowing the original size can speed up the extraction to memory, as you +don't need to call realloc() for many times. + + +The "sametypesequence" option is described in further detail below. + +*** +sametypesequence + +You should first familiarize yourself with the .dict file format +described in the next section so that you can understand what effect +this option has on the .dict file. + +If the sametypesequence option is set, it tells StarDict that each +word's data in the .dict file will have the same sequence of datatypes. +In this case, we expect a .dict file that's been optimized in two +ways: the type identifiers should be omitted, and the size marker for +the last data entry of each word should be omitted. + +Let's consider some concrete examples of the sametypesequence option. + +Suppose that a dictionary records many .wav files, and so sets: + sametypesequence=W +In this case, each word's entry in the .dict file consists solely of a +wav file. In the .dict file, you would leave out the 'W' character +before each entry, and you would also omit the 32-bit integer at the +front of each .wav entry that would normally give the entry's length. +You can do this since the length is known from the information in the +idx file. + +As another example, suppose a dictionary contains phonetic information +and a meaning for each word. The sametypesequence option for this +dictionary would be: + sametypesequence=tm +Once again, you can omit the 't' and 'm' characters before each data +entry in the .dict file. In addition, you should omit the terminating +'\0' for the 'm' entry for each word in the .dict file, as the length +of the meaning string can be inferred from the length of the phonetic +string (still indicated by a terminating '\0') and the length of the +entire word entry (listed in the .idx file). + +So for cases where the last data entry for each word normally requires +a terminating '\0' character, you should omit this character in the +dict file. And for cases where the last data entry for each word +normally requires an initial 32-bit number giving the length of the +field (such as WAV and PNG entries), you must omit this number in the +dictionary. + +Every dictionary should try to use the sametypesequence feature to +save disk space. +*** + + +{3}. The ".idx" file's format. +The .idx file is just a word list. + +The word list is a sorted list of word entries. + +Each entry in the word list contains three fields, one after the other: + word_str; // a utf-8 string terminated by '\0'. + word_data_offset; // word data's offset in .dict file + word_data_size; // word data's total size in .dict file + +word_str gives the string representing this word. It's the string +that is "looked up" by the StarDict. + +Two or more entries may have the same "word_str" with different +word_data_offset and word_data_size. This may be useful for some +dictionaries. But this feature is only well supported by +StarDict-2.4.8 and newer. + +The length of "word_str" should be less than 256. In other words, +(strlen(word) < 256). + +word_data_offset and word_data_size should both be 32-bit unsigned numbers +in network byte order. + +It is possible the different word_str have the same word_data_offset and +word_data_size, so multiple word index point to the same definition. +But this is not recommended, for mutiple words have the same definition, +you may create a ".syn" file for them, see section 4 below. + +The word list must be sorted by calling stardict_strcmp() on the "word_str" +fields. If the word list order is wrong, StarDict will fail to function +correctly! + +============ +gint stardict_strcmp(const gchar *s1, const gchar *s2) +{ + gint a; + a = g_ascii_strcasecmp(s1, s2); + if (a == 0) + return strcmp(s1, s2); + else + return a; +} +============ +g_ascii_strcasecmp() is a glib function: +Unlike the BSD strcasecmp() function, this only recognizes standard +ASCII letters and ignores the locale, treating all non-ASCII characters +as if they are not letters. + +stardict_strcmp() works fine with English characters, but the other +locale characters' sorting is not so good, in this case, you can enable +the collation feature, see section 6. + + +{4}. The ",syn" file's format. +This file is optional, and you should notice tree dictionary needn't this file. +Only StarDict-2.4.8 and newer support this file. + +The .syn file contains information for synonyms, that means, when you input a +synonym, StarDict will search another word that related to it. + +The format is simple. Each item contain one string and a number. +synonym_word; // a utf-8 string terminated by '\0'. +original_word_index; // original word's index in .idx file. +Then other items without separation. +When you input synonym_word, StarDict will search original_word; + +The length of "synonym_word" should be less than 256. In other +words, (strlen(word) < 256). +original_word_index is a 32-bit unsigned number in network byte order. +Two or more items may have the same "synonym_word" with different +original_word_index. +The items must be sorted by stardict_strcmp() with synonym_word. + + +{5}. The offset cache file's format. +StarDict-2.4.8 start to support cache files, this feature can speed up +loading and save memory as mmap() the cache file. The cache file names +are .idx.oft and .syn.oft, the format is: +First a utf-8 string terminated by '\0', then many 32-bit numbers as +the wordoffset index, this index is sparse, and "ENTR_PER_PAGE=32", +they are not stored in network byte order. +The string must begin with: +===== +StarDict's oft file +version=2.4.8 +===== +Then a line like this: +url=/usr/share/stardict/dic/stardict-somedict-2.4.2/somedict.idx +This line should have a ending '\n'. + +StarDict will try to create the .oft file at the same directory of +the .ifo file first, if failed, then try to create it at +~/.cache/stardict/, ~/.cache is get by g_get_user_cache_dir(). +If two or more dictionaries have the same file name, StarDict will +create somedict.idx.oft, somedict(2).idx.oft, somedict(3).idx.oft, +etc. for them respectively, each with different "url=" in the +beginning string. + + +{6}. The collation file's format. +StarDict-2.4.8 start to support collation, that sort the word +list by collate function. It will create collation file which +names .idx.clt and .syn.clt, the format is a little like offset +cache file: +First a utf-8 string terminated by '\0', then many 32-bit numbers as +the index that sorted by the collate function, they are not stored +in network byte order. +The string must begin with: +===== +StarDict's clt file +version=2.4.8 +===== +Then two lines like this: +url=/usr/share/stardict/dic/stardict-somedict-2.4.2/somedict.idx +func=0 +The second line should have a ending '\n' too. + +StarDict support these collate functions currently: +typedef enum { + UTF8_GENERAL_CI = 0, + UTF8_UNICODE_CI, + UTF8_BIN, + UTF8_CZECH_CI, + UTF8_DANISH_CI, + UTF8_ESPERANTO_CI, + UTF8_ESTONIAN_CI, + UTF8_HUNGARIAN_CI, + UTF8_ICELANDIC_CI, + UTF8_LATVIAN_CI, + UTF8_LITHUANIAN_CI, + UTF8_PERSIAN_CI, + UTF8_POLISH_CI, + UTF8_ROMAN_CI, + UTF8_ROMANIAN_CI, + UTF8_SLOVAK_CI, + UTF8_SLOVENIAN_CI, + UTF8_SPANISH_CI, + UTF8_SPANISH2_CI, + UTF8_SWEDISH_CI, + UTF8_TURKISH_CI, +} CollateFunctions; +These UTF8_*_CI functions comes from MySQL in fact. + +The file's locate path just like the .oft file. + +Notice, for "somedict.idx.gz" file, the corresponding collation +file is somedict.idx.clt, but not somedict.idx.gz.clt, the +"url=" is somedict.idx, not somedict.idx.gz. So after you gzip +the .idx file, StarDict needn't create the .clt file again. + + +{7}. The ".dict" file's format. +The .dict file is a pure data sequence, as the offset and size of each +word is recorded in the corresponding .idx file. + +If the "sametypesequence" option is not used in the .ifo file, then +the .dict file has fields in the following order: +============== +word_1_data_1_type; // a single char identifying the data type +word_1_data_1_data; // the data +word_1_data_2_type; +word_1_data_2_data; +...... // the number of data entries for each word is determined by + // word_data_size in .idx file +word_2_data_1_type; +word_2_data_1_data; +...... +============== +It's important to note that each field in each word indicates its +own length, as described below. The number of possible fields per +word is also not fixed, and is determined by simply reading data until +you've read word_data_size bytes for that word. + + +Suppose the "sametypesequence" option is used in the .idx file, and +the option is set like this: +sametypesequence=tm +Then the .dict file will look like this: +============== +word_1_data_1_data +word_1_data_2_data +word_2_data_1_data +word_2_data_2_data +...... +============== +The first data entry for each word will have a terminating '\0', but +the second entry will not have a terminating '\0'. The omissions of +the type chars and of the last field's size information are the +optimizations required by the "sametypesequence" option described +above. + + +Type identifiers +---------------- +Here are the single-character type identifiers that may be used with +the "sametypesequence" option in the .idx file, or may appear in the +dict file itself if the "sametypesequence" option is not used. + +Lower-case characters signify that a field's size is determined by a +terminating '\0', while upper-case characters indicate that the data +begins with a 32-bit unsigned integer that gives the length of the data +field. + +'m' +Word's pure text meaning. +The data should be a utf-8 string ending with '\0'. + +'l' +Word's pure text meaning. +The data is NOT a utf-8 string, but is instead a string in locale +encoding, ending with '\0'. Sometimes using this type will save disk +space, but its use is discouraged. + +'g' +A utf-8 string which is marked up with the Pango text markup language. +For more information about this markup language, See the "Pango +Reference Manual." +You might have it installed locally at: +file:///usr/share/gtk-doc/html/pango/PangoMarkupFormat.html + +'t' +English phonetic string. +The data should be a utf-8 string ending with '\0'. + +Here are some utf-8 phonetic characters: +θʃŋʧðʒæıʌʊɒɛəɑɜɔˌˈːˑṃṇḷ +æɑɒʌәєŋvθðʃʒɚːɡˏˊˋ + +'x' +A utf-8 string which is marked up with the xdxf language. +See http://xdxf.sf.net + +'y' +Chinese YinBiao or Japanese KANA. +The data should be a utf-8 string ending with '\0'. + +'k' +KingSoft PowerWord's data. The data is a utf-8 string ending with '\0'. +It is in XML format. + +'w' +MediaWiki markup language. +See http://meta.wikimedia.org/wiki/Help:Editing#The_wiki_markup + +'W' +wav file. +The data begins with a network byte-ordered guint32 to identify the wav +file's size, immediately followed by the file's content. + +'P' +png file. +The data begins with a network byte-ordered guint32 to identify the png +file's size, immediately followed by the file's content. + +'X' +this type identifier is reserved for experimental extensions. + + +{8}. Tree Dictionary +The tree dictionary support is used for information viewing, etc. + +A tree dictionary contains three file: sometreedict.ifo, sometreedict.tdx.gz +and sometreedict.dict.dz. + +It is better to compress the .tdx file, as it is always load into memory. + +The .ifo file has the following format: + +StarDict's treedict ifo file +version=2.4.2 +[options] + +Available options: + +bookname= // required +tdxfilesize= // required +wordcount= +author= +email= +website= +description= +date= +sametypesequence= + +wordcount is only used for info view in the dict manage dialog, so it is not +important in tree dictionary. + +The .tdx file is just the word list. +----------- +The word list is a tree list of word entries. + +Each entry in the word list contains four fields, one after the other: + word_str; // a utf-8 string terminated by '\0'. + word_data_offset; // word data's offset in .dict file + word_data_size; // word data's total size in .dict file. it can be 0. + word_subentry_count; //have many sub word this entry has, 0 means none. + +Subentry is immidiately followed by its parent entry. This make the order is +just as when a tree list with all its nodes extended, then sort from top to +bottom. + +word_data_offset, word_data_size and word_subentry_count should be 32-bit +unsigned numbers in network byte order. + +The .dict file's format is the same as the normal dictionary. + + + +{9}. More information. +You can read "src/lib.cpp", "src/dictmanagedlg.cpp" and +"src/tools/*.cpp" for more information. + +After you have build a dictionary, you can use "stardict_verify" to verify the +dictionary files. You can find it at "src/tools/". + +If you have any questions, email me. :) + +Thanks to Will Robinson for cleaning up this file's +English. + +Hu Zheng +http://forlinux.yeah.net +2006.6.15 diff --git a/src/plugins/stardict/include/data.h b/src/plugins/stardict/include/data.h new file mode 100644 index 0000000..fdb4ec9 --- /dev/null +++ b/src/plugins/stardict/include/data.h @@ -0,0 +1,57 @@ +/* data.h -- + * Created: Sat Mar 15 18:04:25 2003 by Aleksey Cheusov + * Copyright 1994-2003 Rickard E. Faith (faith@dict.org) + * + * 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 1, 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: data.h,v 1.1 2003/03/19 16:43:15 cheusov Exp $ + */ + +#ifndef _DATA_H_ +#define _DATA_H_ + +//#include "dictP.h" +#include "defs.h" + +/* initialize .data file */ +extern dictData *dict_data_open ( + const char *filename, int computeCRC); +/* */ +extern void dict_data_close ( + dictData *data); + +//extern void dict_data_print_header( FILE *str, dictData *data ); +extern int dict_data_zip( + const char *inFilename, const char *outFilename, + const char *preFilter, const char *postFilter ); +#ifdef ORIGINAL_DICTZIP +extern char *dict_data_obtain ( + const dictDatabase *db, + const dictWord *dw); +#endif +extern char *dict_data_read_ ( + dictData *data, + unsigned long start, unsigned long end, + const char *preFilter, + const char *postFilter ); +#ifdef ORIGINAL_DICTZIP +extern int dict_data_filter( + char *buffer, int *len, int maxLength, + const char *filter ); + +extern int mmap_mode; +#endif + +#endif /* _DATA_H_ */ diff --git a/src/plugins/stardict/include/defs.h b/src/plugins/stardict/include/defs.h new file mode 100644 index 0000000..e93a603 --- /dev/null +++ b/src/plugins/stardict/include/defs.h @@ -0,0 +1,279 @@ +/* defs.h -- + * Created: Sat Mar 15 17:27:23 2003 by Aleksey Cheusov + * Copyright 1994-2003 Rickard E. Faith (faith@dict.org) + * + * 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 1, 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: defs.h,v 1.11 2005/03/29 17:55:50 cheusov Exp $ + */ + +#ifndef _DEFS_H_ +#define _DEFS_H_ + +//#include "dictP.h" +//#include "dictdplugin.h" + +#include +//#include + + /* Configurable things */ + +#define DICT_DEFAULT_SERVICE "2628" /* Also in dict.h */ +#define DICTD_CONFIG_NAME "dictd.conf" +#define DICT_QUEUE_DEPTH 10 +#define DICT_DEFAULT_DELAY 600 /* 10 minute timeout */ +#define DICT_DAEMON_LIMIT 100 /* maximum simultaneous daemons */ +#define DICT_PERSISTENT_PRESTART 3 /* not implemented */ +#define DICT_PERSISTENT_LIMIT 5 /* not implemented */ + +#define DICT_ENTRY_PREFIX "00-database" +#define DICT_ENTRY_PREFIX_LEN sizeof(DICT_ENTRY_PREFIX)-1 +#define DICT_SHORT_ENTRY_NAME DICT_ENTRY_PREFIX"-short" +#define DICT_LONG_ENTRY_NAME DICT_ENTRY_PREFIX"-long" +#define DICT_INFO_ENTRY_NAME DICT_ENTRY_PREFIX"-info" + +#define DICT_FLAG_UTF8 DICT_ENTRY_PREFIX"-utf8" +#define DICT_FLAG_8BIT_NEW DICT_ENTRY_PREFIX"-8bit-new" +#define DICT_FLAG_8BIT_OLD DICT_ENTRY_PREFIX"-8bit" +#define DICT_FLAG_ALLCHARS DICT_ENTRY_PREFIX"-allchars" +#define DICT_FLAG_VIRTUAL DICT_ENTRY_PREFIX"-virtual" +#define DICT_FLAG_ALPHABET DICT_ENTRY_PREFIX"-alphabet" +#define DICT_FLAG_DEFAULT_STRAT DICT_ENTRY_PREFIX"-default-strategy" +#define DICT_FLAG_MIME_HEADER DICT_ENTRY_PREFIX"-mime-header" + +#define DICT_ENTRY_PLUGIN DICT_ENTRY_PREFIX"-plugin" +#define DICT_ENTRY_PLUGIN_DATA DICT_ENTRY_PREFIX"-plugin-data" + +#define DICT_PLUGINFUN_OPEN "dictdb_open" +#define DICT_PLUGINFUN_ERROR "dictdb_error" +#define DICT_PLUGINFUN_FREE "dictdb_free" +#define DICT_PLUGINFUN_SEARCH "dictdb_search" +#define DICT_PLUGINFUN_CLOSE "dictdb_close" +#define DICT_PLUGINFUN_SET "dictdb_set" + + /* End of configurable things */ + +#define BUFFERSIZE 10240 + +#define DBG_VERBOSE (0<<30|1<< 0) /* Verbose */ +#define DBG_ZIP (0<<30|1<< 1) /* Zip */ +#define DBG_UNZIP (0<<30|1<< 2) /* Unzip */ +#define DBG_SEARCH (0<<30|1<< 3) /* Search */ +#define DBG_SCAN (0<<30|1<< 4) /* Config file scan */ +#define DBG_PARSE (0<<30|1<< 5) /* Config file parse */ +#define DBG_INIT (0<<30|1<< 6) /* Database initialization */ +#define DBG_PORT (0<<30|1<< 7) /* Log port number for connections */ +#define DBG_LEV (0<<30|1<< 8) /* Levenshtein matching */ +#define DBG_AUTH (0<<30|1<< 9) /* Debug authentication */ +#define DBG_NODETACH (0<<30|1<<10) /* Don't detach as a background proc. */ +#define DBG_NOFORK (0<<30|1<<11) /* Don't fork (single threaded) */ +#define DBG_ALT (0<<30|1<<12) /* altcompare() */ + +#define LOG_SERVER (0<<30|1<< 0) /* Log server diagnostics */ +#define LOG_CONNECT (0<<30|1<< 1) /* Log connection information */ +#define LOG_STATS (0<<30|1<< 2) /* Log termination information */ +#define LOG_COMMAND (0<<30|1<< 3) /* Log commands */ +#define LOG_FOUND (0<<30|1<< 4) /* Log words found */ +#define LOG_NOTFOUND (0<<30|1<< 5) /* Log words not found */ +#define LOG_CLIENT (0<<30|1<< 6) /* Log client */ +#define LOG_HOST (0<<30|1<< 7) /* Log remote host name */ +#define LOG_TIMESTAMP (0<<30|1<< 8) /* Log with timestamps */ +#define LOG_MIN (0<<30|1<< 9) /* Log a few minimal things */ +#define LOG_AUTH (0<<30|1<<10) /* Log authentication denials */ + +#define DICT_LOG_TERM 0 +#define DICT_LOG_DEFINE 1 +#define DICT_LOG_MATCH 2 +#define DICT_LOG_NOMATCH 3 +#define DICT_LOG_CLIENT 4 +#define DICT_LOG_TRACE 5 +#define DICT_LOG_COMMAND 6 +#define DICT_LOG_AUTH 7 +#define DICT_LOG_CONNECT 8 + +#define DICT_UNKNOWN 0 +#define DICT_TEXT 1 +#define DICT_GZIP 2 +#define DICT_DZIP 3 + +#define DICT_CACHE_SIZE 5 + +typedef struct dictCache { + int chunk; + char *inBuffer; + int stamp; + int count; +} dictCache; + +typedef struct dictData { + int fd; /* file descriptor */ + const char *start; /* start of mmap'd area */ + const char *end; /* end of mmap'd area */ + unsigned long size; /* size of mmap */ + + int type; + const char *filename; + z_stream zStream; + int initialized; + + int headerLength; + int method; + int flags; + time_t mtime; + int extraFlags; + int os; + int version; + int chunkLength; + int chunkCount; + int *chunks; + unsigned long *offsets; /* Sum-scan of chunks. */ + const char *origFilename; + const char *comment; + unsigned long crc; + unsigned long length; + unsigned long compressedLength; + dictCache cache[DICT_CACHE_SIZE]; +} dictData; + +typedef struct dictPlugin { + void * data; + +#ifdef USE_PLUGIN +/* lt_dlhandle handle; + + dictdb_open_type dictdb_open; + dictdb_set_type dictdb_set; + dictdb_search_type dictdb_search; + dictdb_free_type dictdb_free; + dictdb_error_type dictdb_error; + dictdb_close_type dictdb_close; + + char dictdb_free_called; *//* 1 after dictdb_free call */ +#endif +} dictPlugin; + +typedef struct dictIndex { + int fd; /* file descriptor */ + const char *start; /* start of mmap'd area */ + const char *end; /* end of mmap'd area */ + unsigned long size; /* size of mmap */ + const char *optStart[UCHAR_MAX+2]; /* Optimized starting points */ + unsigned long headwords; /* computed number of headwords */ + + int flag_utf8; /* not zero if it has 00-database-utf8 entry*/ + int flag_8bit; /* not zero if it has 00-database-8bit-new entry*/ + int flag_allchars; /* not zero if it has 00-database-allchars entry*/ + + const int *isspacealnum; +} dictIndex; + +#ifdef ORIGINAL_DICTZIP + +typedef struct dictDatabase { + const char *databaseName; + const char *databaseShort; + const char *databaseInfo; + const char *dataFilename; + const char *indexFilename; + const char *indexsuffixFilename; + const char *indexwordFilename; + const char *filter; + const char *prefilter; + const char *postfilter; + lst_List acl; + int available; /* if user has authenticated for database */ + + dictData *data; + dictIndex *index; + dictIndex *index_suffix; + dictIndex *index_word; + + int *strategy_disabled; /* disable_strategy keyword*/ + + lst_List *virtual_db_list; + + char *alphabet; + + int invisible; /* non-zero for invisible databases */ + + int exit_db; /* non-zero for dictionary_exit entry */ + int virtual_db; /* non-zero for virtual databases */ + int plugin_db; /* non-zero for plugin entry */ + int normal_db; /* non-zero for normal database */ + int mime_db; /* non-zero for MIME database */ + + int default_strategy; /* default search strategy for `.' */ + + const char *mime_header; /* MIME header for OPTION MIME command */ + + /* database_virtual members */ + const char *database_list; /* comma-separated list of database names */ + + /* database_plugin members */ + const char *pluginFilename; + const char *plugin_data; /* data for initializing plugin */ + dictPlugin *plugin; + + /* database_mime members */ + const char *mime_mimeDbname; + const char *mime_nomimeDbname; + + struct dictDatabase *mime_mimeDB; + struct dictDatabase *mime_nomimeDB; +} dictDatabase; + +#define DICT_DENY 0 +#define DICT_ALLOW 1 +#define DICT_AUTHONLY 2 +#define DICT_USER 3 +#define DICT_GROUP 4 /* Not implemented */ +#define DICT_MATCH 5 /* For IP matching routines */ +#define DICT_NOMATCH 6 /* For IP matching routines */ + +typedef struct dictAccess { + int type; /* deny, allow, accessonly, user, group */ + const char *spec; +} dictAccess; + +typedef struct dictConfig { + lst_List acl; /* type dictAccess */ + lst_List dbl; /* type dictDatabase */ + hsh_HashTable usl; /* username/shared-secret list */ + const char *site; +} dictConfig; + +typedef struct dictWord { + const dictDatabase *database; + const dictDatabase *database_visible; + + char *word; + + unsigned long start; + unsigned long end; + +/* Used by plugins */ + const char *def; + int def_size; +} dictWord; + +typedef struct dictToken { + const char *string; + int integer; + src_Type src; +} dictToken; + +#endif + +#endif /* _DEFS_H_ */ diff --git a/src/plugins/stardict/include/dictP.h b/src/plugins/stardict/include/dictP.h new file mode 100644 index 0000000..6a3a3c4 --- /dev/null +++ b/src/plugins/stardict/include/dictP.h @@ -0,0 +1,343 @@ + +/* dictP.h -- + * Created: Fri Mar 7 10:54:05 1997 by faith@dict.org + * Revised: Fri Dec 22 06:06:33 2000 by faith@dict.org + * Copyright 1997, 1999, 2000 Rickard E. Faith (faith@dict.org) + * This program comes with ABSOLUTELY NO WARRANTY. + * + * 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 1, 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: dictP.h,v 1.22 2005/09/05 18:00:02 cheusov Exp $ + * + */ + +#ifndef _DICTP_H_ +#define _DICTP_H_ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(__INTERIX) || defined(__OPENNT) +#ifndef _ALL_SOURCE +#define _ALL_SOURCE +#endif /* _ALL_SOURCE */ +#endif /* __OPENNT */ + +#include +#include +#include +#include +#include +#include + +#if defined(HAVE_WCTYPE_H) && defined(SYSTEM_UTF8_FUNCS) +#include +#endif + +#ifdef HAVE_CTYPE_H +#include +#endif + +#ifndef __GNUC__ +#define __FUNCTION__ __FILE__ +#endif + +/* AIX requires this to be the first thing in the file. */ +#if defined(__svr4__) && defined(__sgi__) && !HAVE_ALLOCA_H /* IRIX */ +# undef HAVE_ALLOCA_H +# define HAVE_ALLOCA_H 1 +#endif + +#ifndef HAVE_ALLOCA +#if HAVE_ALLOCA_H +# include +#else +# ifdef _AIX +# pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +# if !defined(__svr4__) && !defined(__sgi__) /* not on IRIX */ + char *alloca (); +# endif +# endif +# endif +#endif +#endif + +/* Get string functions */ +#if STDC_HEADERS +# include +#else +# if HAVE_STRINGS_H +# include +# endif +# if !HAVE_STRCHR +# define strchr index +# define strrchr rindex +# endif +# if !HAVE_MEMCPY +# define memcpy(d, s, n) bcopy ((s), (d), (n)) +# define memmove(d, s, n) bcopy ((s), (d), (n)) +# endif +#endif + +#if HAVE_SIZE_T +#include +#else +typedef unsigned int size_t; +#endif + +#if !HAVE_STRDUP +extern char *strdup( const char * ); +#endif + +#if !HAVE_STRTOL +extern long strtol( const char *, char **, int ); +#endif + +#if !HAVE_STRTOUL +extern unsigned long int strtoul( const char *, char **, int ); +#endif + +#if !HAVE_SNPRINTF +extern int snprintf(char *str, size_t size, const char *format, ...); +#endif + +#if !HAVE_VSNPRINTF +#include +extern int vsnprintf(char *str, size_t size, const char *format, va_list ap); +#endif + +#if !HAVE_INET_ATON +#define inet_aton(a,b) (b)->s_addr = inet_addr(a) +#endif + +#if HAVE_WINT_T +#include +#else +typedef unsigned int wint_t; +#endif + +#if !HAVE_ISWALNUM +extern int iswalnum__ (wint_t wc); +#else +#define iswalnum__ iswalnum +#endif + +#if !HAVE_ISWSPACE +extern int iswspace__ (wint_t wc); +#else +#define iswspace__ iswspace +#endif + +#if !HAVE_TOWLOWER +extern wint_t towlower__ (wint_t wc); +#else +#define towlower__ towlower +#endif + +#if HAVE_WCHAR_T +#include +#else +typedef unsigned int wchar_t; +#endif + +#if HAVE_DECL_CODESET +#include +#else +extern const char * nl_langinfo (int ITEM); +#define CODESET 1234 +#endif + +#ifndef SYSTEM_UTF8_FUNCS +#define MB_CUR_MAX__ 6 +#else +#define MB_CUR_MAX__ MB_CUR_MAX +#endif + +#if HAVE_MBSTATE_T +#include +#else +typedef char mbstate_t; +#endif + +#if !HAVE_STRLCPY +extern size_t strlcpy (char *s, const char * wc, size_t size); +#endif + +#if !HAVE_STRLCAT +size_t strlcat(char *dst, const char *src, size_t siz); +#endif + +#if !HAVE_WCRTOMB +extern size_t wcrtomb__ (char *s, wchar_t wc, mbstate_t *ps); +#else +#define wcrtomb__ wcrtomb +#endif + +#if !HAVE_WCTOMB +extern int wctomb__ (char *s, wchar_t wc); +#else +#define wctomb__ wctomb +#endif + +#if !HAVE_MBRLEN +extern size_t mbrlen__ (const char *s, size_t n, mbstate_t *ps); +#else +#define mbrlen__ mbrlen +#endif + +#if !HAVE_MBRTOWC +extern size_t mbrtowc__ (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps); +#else +#define mbrtowc__ mbrtowc +#endif + +#if !HAVE_MBSTOWCS +extern size_t mbstowcs__ (wchar_t *dest, const char *src, size_t n); +#else +#define mbstowcs__ mbstowcs +#endif + +#if !HAVE_SETENV +extern int setenv(const char *name, const char *value, int overwrite); +#endif + +#if !HAVE_MBTOWC +extern int mbtowc__ (wchar_t *pwc, const char *s, size_t n); +#else +#define mbtowc__ mbtowc +#endif + +#if !HAVE_WCWIDTH +#define wcwidth__(x) (1) +#endif + +#if !HAVE_INITGROUPS +#define initgroups(a,b) +#endif + +#if defined(HAVE_WAITPID) && !defined(HAVE_WAIT3) +#define wait3(status,options,rusage) \ + waitpid(-1, (status),(options)) +#endif + +#if USE_PLUGIN +# if HAVE_DLFCN_H +# include + typedef void * lt_dlhandle; +# define lt_dlsym dlsym +# define lt_dlopen(filename) dlopen(filename, RTLD_NOW) +# define lt_dlclose dlclose +# define lt_dlerror dlerror +# else +# include +# endif +#endif + +/* Get time functions */ +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +/* Include some standard header files. */ +#include +#if HAVE_UNISTD_H +# include +# include +# include +#endif + +/* Always use local (libmaa) getopt */ +#include + +/* We actually need a few non-ANSI C things... */ +#if defined(__STRICT_ANSI__) +extern char *strdup( const char * ); +extern int fileno( FILE *stream ); +extern FILE *fdopen( int fildes, const char *mode ); +extern void bcopy( const void *src, void *dest, int n ); +extern long int random( void ); +extern void srandom( unsigned int ); +#endif + +#if HAVE_SYS_RESOURCE_H +# include +#endif + +/* Provide assert() */ +#include + +/* Provide stdarg support */ +#include + +/* Provide networking stuff */ +#if HAVE_SYS_WAIT_H +# include +#endif +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + +#include +#include +#include + +/* Provide mmap stuff */ +#ifdef HAVE_MMAP +#include +#endif + +/* System dependent declarations: Many brain damaged systems don't provide +declarations for standard library calls. We provide them here for +situations that we know about. */ +#include "decl.h" + +#if HAVE_LIMITS_H +#include +#endif + +/* Handle getopt correctly */ +#if HAVE_GETOPT_H +# include +#else +#if !HAVE_GETOPT_LONG +int getopt_long(int argc, char * const argv[], + const char *optstring, + const struct option *longopts, int *longindex); +extern int optind; +extern char *optarg; +#endif +#endif + + /* Local stuff */ +#ifndef max +#define max(a,b) ((a)>(b)?(a):(b)) +#endif + +#define HAVE_UTF8 1 + +#endif /* _DICTP_H_ */ diff --git a/src/plugins/stardict/include/dictd.h b/src/plugins/stardict/include/dictd.h new file mode 100644 index 0000000..0e68b9c --- /dev/null +++ b/src/plugins/stardict/include/dictd.h @@ -0,0 +1,127 @@ +/* dictd.h -- Header file for dict program + * Created: Fri Dec 2 20:01:18 1994 by faith@dict + * Revised: Mon Apr 22 15:47:26 2002 by faith@dict.org + * Copyright 1994-2000, 2002 Rickard E. Faith (faith@dict.org) + * + * 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 1, 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef _DICTD_H_ +#define _DICTD_H_ + +#include "dictP.h" +#include "maa.h" +#include "codes.h" +#include "defs.h" + +#include "net.h" +#include + +#include +#include +/* +#ifdef __osf__ +#define _XOPEN_SOURCE_EXTENDED +#endif +#include +#include +#include +*/ + +extern const char *daemon_service; +extern int client_delay; +extern int depth; +extern int _dict_daemon_limit; +extern int _dict_markTime; +extern const char *logFile; +extern const char *pidFile; +extern int logOptions; +extern const char *bind_to; +extern int useSyslog; +extern const char *logFile; + +extern int daemon_service_set; +extern int logFile_set; +extern int pidFile_set; +extern int _dict_markTime_set; +extern int client_delay_set; +extern int depth_set; +extern int _dict_daemon_limit_set; +extern int syslog_facility_set; +extern int locale_set; +extern int default_strategy_set; +extern int bind_to_set; + + + + +extern void dict_disable_strat (dictDatabase *db, const char* strat); + +extern void dict_dump_list( lst_List list ); +extern void dict_destroy_list( lst_List list ); + +extern int dict_destroy_datum( const void *datum ); + +#ifdef USE_PLUGIN +extern int dict_plugin_open (dictDatabase *db); +extern void dict_plugin_close (dictDatabase *db); +#endif + +/* dictd.c */ + +extern void set_minimal (void); + +extern void dict_initsetproctitle( int argc, char **argv, char **envp ); +extern void dict_setproctitle( const char *format, ... ); +extern const char *dict_format_time( double t ); +extern const char *dict_get_hostname( void ); +extern const char *dict_get_banner( int shortFlag ); + +extern dictConfig *DictConfig; /* GLOBAL VARIABLE */ +extern int _dict_comparisons; /* GLOBAL VARIABLE */ +extern int _dict_forks; /* GLOBAL VARIABLE */ +extern const char *locale; + +extern const char *locale; +extern int inetd; /* 1 if --inetd is applied, 0 otherwise */ + +/* + If the filename doesn't start with / or ., + it is prepended with DICT_DIR +*/ +extern const char *postprocess_dict_filename (const char *fn); +/* + If the filename doesn't start with / or ., + it is prepended with PLUGIN_DIR +*/ +extern const char *postprocess_plugin_filename (const char *fn); + +/* daemon.c */ + +extern int dict_daemon( int s, struct sockaddr_in *csin, char ***argv0, + int delay_, int error ); +extern int dict_inetd( char ***argv0, int delay_, int error ); +extern void daemon_terminate( int sig, const char *name ); + +/* */ +extern int utf8_mode; + + /* dmalloc must be last */ +#ifdef DMALLOC_FUNC_CHECK +# include "dmalloc.h" +#endif + +#endif diff --git a/src/plugins/stardict/include/dictzip.h b/src/plugins/stardict/include/dictzip.h new file mode 100644 index 0000000..163cc26 --- /dev/null +++ b/src/plugins/stardict/include/dictzip.h @@ -0,0 +1,120 @@ +/* dictzip.h -- Header file for dict program + * Created: Fri Dec 2 20:01:18 1994 by faith@dict.org + * Revised: Fri Dec 22 06:06:31 2000 by faith@dict.org + * Copyright 1994, 1995, 1996, 1997, 2000 Rickard E. Faith (faith@dict.org) + * + * 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 1, 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef _DICTZIP_H_ +#define _DICTZIP_H_ + +//#include "maa.h" +#include +//#include "dictd.h" + + /* End of configurable things */ + +#define BUFFERSIZE 10240 +#define DBG_VERBOSE (0<<30|1<< 0) /* Verbose */ +#define DBG_ZIP (0<<30|1<< 1) /* Zip */ +#define DBG_UNZIP (0<<30|1<< 2) /* Unzip */ +#define DBG_SEARCH (0<<30|1<< 3) /* Search */ +#define DBG_SCAN (0<<30|1<< 4) /* Config file scan */ +#define DBG_PARSE (0<<30|1<< 5) /* Config file parse */ +#define DBG_INIT (0<<30|1<< 6) /* Database initialization */ + +#define HEADER_CRC 0 /* Conflicts with gzip 1.2.4 */ + +/* Use of the FEXTRA fields. The FEXTRA area can be 0xffff bytes long, 2 + bytes of which are used for the subfield ID, and 2 bytes of which are + used for the subfield length. This leaves 0xfffb bytes (0x7ffd 2-byte + entries or 0x3ffe 4-byte entries). Given that the zip output buffer must + be 10% + 12 bytes larger than the input buffer, we can store 58969 bytes + per entry, or about 1.8GB if the 2-byte entries are used. If this + becomes a limiting factor, another format version can be selected and + defined for 4-byte entries. */ + + + /* Output buffer must be greater than or + equal to 110% of input buffer size, plus + 12 bytes. */ +#define OUT_BUFFER_SIZE 0xffffL + +#define IN_BUFFER_SIZE ((unsigned long)((double)(OUT_BUFFER_SIZE - 12) * 0.89)) + +#define PREFILTER_IN_BUFFER_SIZE (IN_BUFFER_SIZE * 0.89) + + +/* For gzip-compatible header, as defined in RFC 1952 */ + + /* Magic for GZIP (rfc1952) */ +#define GZ_MAGIC1 0x1f /* First magic byte */ +#define GZ_MAGIC2 0x8b /* Second magic byte */ + + /* FLaGs (bitmapped), from rfc1952 */ +#define GZ_FTEXT 0x01 /* Set for ASCII text */ +#define GZ_FHCRC 0x02 /* Header CRC16 */ +#define GZ_FEXTRA 0x04 /* Optional field (random access index) */ +#define GZ_FNAME 0x08 /* Original name */ +#define GZ_COMMENT 0x10 /* Zero-terminated, human-readable comment */ +#define GZ_MAX 2 /* Maximum compression */ +#define GZ_FAST 4 /* Fasted compression */ + + /* These are from rfc1952 */ +#define GZ_OS_FAT 0 /* FAT filesystem (MS-DOS, OS/2, NT/Win32) */ +#define GZ_OS_AMIGA 1 /* Amiga */ +#define GZ_OS_VMS 2 /* VMS (or OpenVMS) */ +#define GZ_OS_UNIX 3 /* Unix */ +#define GZ_OS_VMCMS 4 /* VM/CMS */ +#define GZ_OS_ATARI 5 /* Atari TOS */ +#define GZ_OS_HPFS 6 /* HPFS filesystem (OS/2, NT) */ +#define GZ_OS_MAC 7 /* Macintosh */ +#define GZ_OS_Z 8 /* Z-System */ +#define GZ_OS_CPM 9 /* CP/M */ +#define GZ_OS_TOPS20 10 /* TOPS-20 */ +#define GZ_OS_NTFS 11 /* NTFS filesystem (NT) */ +#define GZ_OS_QDOS 12 /* QDOS */ +#define GZ_OS_ACORN 13 /* Acorn RISCOS */ +#define GZ_OS_UNKNOWN 255 /* unknown */ + +#define GZ_RND_S1 'R' /* First magic for random access format */ +#define GZ_RND_S2 'A' /* Second magic for random access format */ + +#define GZ_ID1 0 /* GZ_MAGIC1 */ +#define GZ_ID2 1 /* GZ_MAGIC2 */ +#define GZ_CM 2 /* Compression Method (Z_DEFALTED) */ +#define GZ_FLG 3 /* FLaGs (see above) */ +#define GZ_MTIME 4 /* Modification TIME */ +#define GZ_XFL 8 /* eXtra FLags (GZ_MAX or GZ_FAST) */ +#define GZ_OS 9 /* Operating System */ +#define GZ_XLEN 10 /* eXtra LENgth (16bit) */ +#define GZ_FEXTRA_START 12 /* Start of extra fields */ +#define GZ_SI1 12 /* Subfield ID1 */ +#define GZ_SI2 13 /* Subfield ID2 */ +#define GZ_SUBLEN 14 /* Subfield length (16bit) */ +#define GZ_VERSION 16 /* Version for subfield format */ +#define GZ_CHUNKLEN 18 /* Chunk length (16bit) */ +#define GZ_CHUNKCNT 20 /* Number of chunks (16bit) */ +#define GZ_RNDDATA 22 /* Random access data (16bit) */ + +#define DICT_UNKNOWN 0 +#define DICT_TEXT 1 +#define DICT_GZIP 2 +#define DICT_DZIP 3 + + +#endif diff --git a/src/plugins/stardict/include/engine API.h b/src/plugins/stardict/include/engine API.h new file mode 100755 index 0000000..86b40da --- /dev/null +++ b/src/plugins/stardict/include/engine API.h @@ -0,0 +1,898 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#ifndef _DICTIONARY_ENGINE_BASE +#define _DICTIONARY_ENGINE_BASE + +#ifdef __cplusplus + extern "C" { +#endif + + +//______________________________________________________________________________ +// ***************************************************************************** +//************************************************************* HEADERS SECTION: +//------------------------------------------------------------------------------ +// header with gnu library for C - most of types and functions needed it (all +// started from g* and g_*(). +#include +//------------------------------------------------------------------------------ + +#define _GLOBAL_FUNCTIONS_NAME_ "engine_global_functions" + +//______________________________________________________________________________ +// ***************************************************************************** +//******************************************************* GLOBAL MACROS SECTION: +//------------------------------------------------------------------------------ +/** \brief Checks if module is peaceable with concrete location. + * + * If user of engine module want to know if concrete module can handle concrete + * location, he can call dict_eng_module_check()and check the result + * of this function. + * + * @param module :: EngineModule - module engine which will be testing + * @param location :: gchar* - location on wich engine will be testing + * @return gboolean :: tells if location location can be + * handled by module module + */ +#define dict_eng_module_check(module,location) \ + ( (module).engine_check( (location) ) ) +//------------------------------------------------------------------------------ +/** \brief Get short description of engine module. + * + * If there is need to present to the user of end programm some information + * about enigne he is using, we can call dict_eng_module_get_description() and + * print/show the result of this call. + * + * @param module :: EngineModule- module engine which description we want + * @return gchar* :: there is string, decribing module engine + * module, in this pointer. User should NOT free this pointer as it + * points to static table of chars + */ +#define dict_eng_module_get_description(module) \ + ( (module).engine_description() ) +//------------------------------------------------------------------------------ +/** \brief Get version of engine module. + * + * Sometimes it could be useful to get know what version of engine module we are + * using. We can call this function to retrieve these informations from module. + * Note that version information could be also placed in description of module, + * but here user will get only string representing version, what could be needed + * in some situation (e.g.: if end-user will have two the same module, then + * programm has to decide which should be used, or ask user). + * + * @param module :: EngineModule - module engine which implementation + * version we want + * @return gchar* :: pointer to string representing module + * moduleversion. User should NOT free this pointer as it points to + * static table of chars + */ +#define dict_eng_module_get_version(module) \ + ( (module).engine_version() ) +//------------------------------------------------------------------------------ +/** \brief Get format on which working engnine module. + * + * If we want to know on what dictionary format works current engine module, we + * can call this function. As a result we will retrieve string telling us what + * format-based is concrete engine module (e.g. XDXF, WordNet etc.). + * + * @param module :: EngineModule - engine module which dictionary format + * we want to get + * @return gchar* :: string representing format of dictionary on + * which module module can works. User should NOT free this pointer as + * it points to static table of chars + */ +#define dict_eng_module_get_format(module) \ + ( (module).engine_version() ) +//------------------------------------------------------------------------------ +/** \brief Open concrete dictionary. + * + * This functions opens location (this could mean: filename, URL, any other way + * to specify concrete localization of dictionary database). To be more sure + * that this function will be sucefull, user can call before + * dict_eng_module_check() to check if this module can handle dictionary under + * passed location. But this do not warrant that calling + * dict_eng_module_create() will not fail. User should check the result of + * function to be sure that everything was ok. + * + * @param module :: EngineModule - engine module which should be used to + * open location location + * @param location :: gchar* - location of dictionary database (file, + * directory, URL etc.) + * @param flags :: EngineOptimizationFlag - flags defines how program + * shoud automaticlly use optimization methods for opened dictionary + * @return Engine* :: pointer to new enigne structure; After use, + * if this structure will not be needed anymore, user should call + * dict_eng_destroy() to free memory + * \sa EngineOptimizationFlag :|: dict_eng_module_check() :|: EngineModule :|: + * Engine +*/ +#define dict_eng_module_create(module,location,flags) \ + ( (module).engine_create( (location), (flags), NULL, NULL, 0.01 ) ) +//------------------------------------------------------------------------------ +/** \brief Open concrete dictionary - define handler for signal of progress + * + * This functions is similiar to dict_eng_module_create(module,location,flags). + * In addition to it, this function get additional parameters, defining how + * engine should "inform" the user about progress of eventuall caching proccess. + * + * @param module :: EngineModule - engine module which should be used to + * open location location + * @param location :: gchar* - location of dictionary database (file, + * directory, URL etc.) + * @param flags :: EngineOptimizationFlag - flags defines how program + * shoud automaticlly use optimization methods for opened dictionary + * @param progress_handler :: cb_progress - handler which will be called + * from time to time, to give to the user any response about caching progress + * @param progress_data :: gpointer - pointer to data which will be given + * as a user_data argument for progress_data function during its calling + * @param seed :: gdouble - defines after how big step (in percentage) + * in progress of caching, engine send new signal - call progress_handler with + * actual value of progress + * @return Engine* :: pointer to new enigne structure; After use, + * if this structure will not be needed anymore, user should call + * dict_eng_destroy() to free memory + * \sa EngineOptimizationFlag :|: dict_eng_module_check() :|: EngineModule :|: + * Engine :|: cb_progress + */ +#define dict_eng_module_create_ext(module, \ + location, \ + flags, \ + progress_handler, \ + progress_data, \ + seed \ + ) ( \ + (module).engine_create( (location), \ + (flags), \ + (progress_handler), \ + (progress_data), \ + (seed) \ + )) +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//****************************************** CONCRETE DICTIONARY MACROS SECTION: +//------------------------------------------------------------------------------ +#define dict_eng_set_progress_seed(engine, signal, val) ( \ + (engine) -> engine_set_progress_seed( (engine), \ + (signal), \ + (val) \ + )) +//------------------------------------------------------------------------------ + +#define dict_eng_set_auto_free(engine, state) ( \ + (engine) -> engine_set_auto_free( (engine), (state) ) +//------------------------------------------------------------------------------ +/** \brief Activate optimization mechanizms for concrete engine. + * + * Every engine could have some optimization methods. By calling this function + * we enabled this option. For the user of engine it is not important what kind + * of optimization is used in current engine, how does it work etc. It should + * be opaque for engine's users. + * + * @param engine :: Engine* - pointer to engine which should optimized + * @return void :: nothing. This function only take a chance to + * make engine working faster, but it is not said that every step + * will be succesful. But even if not - engine has to work properly. + * \sa dict_eng_module_create() :|: dict_eng_is_optimized() :|: Engine + */ +#define dict_eng_optimize(engine) \ + ((engine) -> engine_optimize( (engine) )) +//------------------------------------------------------------------------------ +/** \brief Checks if current engine has activated optimization. + * + * User can call this function to get know if concrete engine has enabled + * optimization. Optimization can be activated by calling dict_eng_optimize() + * or passing ENGINE_CREATE or ENGINE_REFRESH flags to dict_eng_module_create() + * while opening concrete dictionary. + * + * @param engine :: Engine* - pointer to engine which should be checked + * if is optimized now + * @return gboolean :: nothing. This function only take a chance + * to make engine working faster, but it is not said that every step + * will be succesful + * \sa dict_eng_optimize() :|: Engine :|: EngineOptimizationFlag + */ +#define dict_eng_is_optimized( engine ) \ + ((engine) -> engine_is_optimized( (engine) )) +//------------------------------------------------------------------------------ +/** \brief To get know from what location was created current dictionary. + * + * If user of engine want to get know from what locatione exactly was created + * concrete engine, he could call this function. It returns string, most likely + * the same as the one passed earlier to dict_eng_module_create() function + * as a location argument. + * + * @param engine :: Engine* - dictionary from which we want to get + * location + * @return gchar* :: pointer to chars, from which concrete + * dictionary was created + * \sa dict_eng_module_create() + */ +#define dict_eng_get_location(engine) \ + ((engine) -> engine_location( (engine) )) +//------------------------------------------------------------------------------ +/** \brief Tells if last operation was sucesfull. + * + * If user want to be sure that everything was ok, during last operation + * (it has finished with success), he has to check if dict_eng_get_last_status() + * is equal to ENGINE_NO_ERROR. If not, he can also find the reason + * why operation failed. + * @param engine :: Engine* - dictionary which last operation's returned + * code we want to get + * @return EngineStatus :: finish code of last operation + * \sa EngineStatus :|: dict_eng_state_message() + */ +#define dict_eng_get_last_status(engine) \ + ((engine) -> engine_error( (engine) )) +//------------------------------------------------------------------------------ +/** \brief Translate pure state code to meaningfull message. + * + * If there was a error during engine was working, we can present to the user + * the reason for this error in meaningfull form. + * + * @param error :: EngineState - code which we want to translate + * @return gchar* :: message describing concrete error code + * \sa EngineStatus :|: dict_eng_state_message() + */ +#define dict_eng_state_message(error) \ + ((engine) -> engine_error_message( (error) )) +//------------------------------------------------------------------------------ +/** \brief Destroy gently and completly current dictionary. + * + * When user do not need anymore concrete dictionary, he must destroy it to + * free memory allocated by this dictionary. It will close avery opened file + * descriptor, free any additional memory block allocated while engine was + * working etc. User are not allowed to call free() on dictionary without + * calling before dict_eng_destroy(). + * + * @param engine :: Engine* - pointer to dictionary which is not + * needed anymore + * @return void :: nothing. This function should work properly, + * and free any resources which arelady are in use by current dictionary. + * \sa dict_eng_module_create() :|: Engine + */ +#define dict_eng_destroy(engine) \ + ((engine) -> engine_close( (engine) )) +//------------------------------------------------------------------------------ +/** \brief Start searching for words list. + * + * This function starts searching for words list. User should set before + * callback for ENGINE_WORD_LIST_SIGNAL, to be able to retrieve words list, + * because this function do not return any value. + * + * @param engine :: Engine* - pointer to dictionary in which we + * are looking for words matching to pattern + * @param pattern :: gchar* - string representing pattern to which + * returned word should be matching + * @return void :: nothing. Result of searching can be retrieved + * by callback for signal ENGINE_WORD_LIST_SIGNAL + * \sa dict_eng_search_word_translation() :|: + * dict_eng_search_word_translation_extended() :|: dict_eng_set_callback() :|: + * ENGINE_WORD_LIST_SIGNAL + */ +#define dict_eng_search_word_list(engine,pattern) \ + ((engine) -> engine_search_word_list( (engine), \ + (pattern) \ + )) +//------------------------------------------------------------------------------ +/** \brief Start searching for word translation in dictionary. + * + * Start searching for translation of word. To be able to retrieve translation + * user should use callback for ENGINE_WORD_TRANSLATION_SIGNAL signal. + * + * @param engine :: Engine* - dictionary in which we want find word's + * translation + * @param word :: gchar* - string representing word which translation + * we are looking for + * @return void :: nothing. Result of searching can be retrieved + * by callback for signal ENGINE_WORD_TRANSLATION_SIGNAL + * \sa dict_eng_search_word_list() :|: + * dict_eng_search_word_translation_extended() :|: dict_eng_set_callback() :|: + * ENGINE_WORD_TRANSLATION_SIGNAL + */ +#define dict_eng_search_word_translation(engine,word) \ + ((engine) -> engine_search_word_translation( (engine), \ + (word) \ + )) +//------------------------------------------------------------------------------ +/** \brief Start searching for extended word translation in dictionary. + * + * Start searching for extended translation of word. To be able to retrieve + * translation user should use callback for ENGINE_WORD_TRANSLATION_SIGNAL + * signal. Extended means that retrieved translation's string could be some more + * than plain text (e.g. HTML, Image, etc.). User of engine should know what + * kind of data will retrieve ofter calling this method. + * + * \todo This option are in projecting phase. In the future callback for + * ENGINE_WORD_TRANSLATION_SIGNAL should take parameter gpointer than + * gchar* to make possible for user of engine to retrieve data different + * than gchar*. There shold be also some additional function letting know user + * what kind of data he will retrieve. + * + * @param engine :: Engine* - dictionary in which we want find word's + * translation + * @param word :: gchar* - string representing word which translation + * we are looking for + * @return void :: nothing. Result of searching can be retrieved + * by callback for signal ENGINE_WORD_TRANSLATION_SIGNAL + * \sa dict_eng_search_word_list() :|: dict_eng_search_word_translation() :|: + * dict_eng_set_callback() :|: ENGINE_WORD_TRANSLATION_SIGNAL + */ +#define dict_eng_search_word_translation_extended(engine,word) \ + ((engine) -> engine_search_word_translation_extended((engine), \ + (pattern) \ + )) +//------------------------------------------------------------------------------ +/** \brief Setting any callback for current dictionary. + * + * As long as functions which search for words list or translation do not + * return any value, user has to set callback which will be called after + * searching end. This make easy calling these functions from other proccess, + * threads etc. This function sets callbacks for every signal. + * + * @param engine :: Engine* - dictionary for which we want set some + * callback + * @param signal :: gchar* - string representing for what signal we want + * to set callback + * @param c_handler :: gpointer - pointer to function which will be + * called after signal signal will occured + * @param data :: gpointer - pointer to user data, which will be always + * passed to callback c_handler for signal signal + * as a last argument + * @return gpointer :: pointer to previous callback; if this + * callbacks was not set yet, it returns NULL + * \sa cb_word_list :|: cb_word_translation :|: ENGINE_WORD_LIST_SIGNAL :|: + * ENGINE_WORD_TRANSLATION_SIGNAL + */ +#define dict_eng_set_callback(engine,signal,c_handler,data) \ + ((engine) -> engine_set_callback( (engine), \ + (signal), \ + (c_handler), \ + (data) \ + )) +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//************************************ SIGNALS DEFINITION FOR CALLBACKS SECTION: +//------------------------------------------------------------------------------ +/** \brief Signal definition for callback called when word list was found. + * + * ENGINE_WORD_LIST_SIGNAL defines name for signal passed to + * dict_eng_set_callback() function as a signal parameter. Function set + * to handle this signal should be called from dict_eng_search_word_list() only + * and have cb_word_list type. + * NOTE: programmers must not use value of ENGINE_WORD_LIST_SIGNAL + * directly! + * \sa cb_word_list :|: dict_eng_set_callback() :|: dict_eng_search_word_list() + * :|: ENGINE_WORD_TRANSLATION_SIGNAL + */ +#define ENGINE_WORD_LIST_SIGNAL "on_word_list_found" +//------------------------------------------------------------------------------ +/** \brief Signal definition for callback called when word trans. was found. + * + * ENGINE_WORD_TRANSLATION_SIGNAL defines name for signal passed to + * dict_eng_set_callback() function as a signal parameter. Function set + * to handle this signal should be called from + * dict_eng_search_word_translation() and + * dict_eng_search_word_translation_extended() only and have cb_word_translation. + * NOTE: programmers must not use value of ENGINE_WORD_LIST_SIGNAL + * directly! + * \sa cb_word_translation :|: dict_eng_set_callback() :|: + * dict_eng_search_word_translation() :|: ENGINE_WORD_LIST_SIGNAL + */ +#define ENGINE_WORD_TRANSLATION_SIGNAL "on_word_translation_found" +//------------------------------------------------------------------------------ +#define ENGINE_PROGRESS_OPTIMIZING_SIGNAL "on_progress_optimizing" +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//************************************************** DEFINITIONS OF ENUMS TYPES: +//------------------------------------------------------------------------------ +/** \brief Codes of flags used to auto optimizing dictionary file. + * + * - Enum type for flags used as a flags parameter for dict_eng_module_create() + * function. + */ +typedef enum +{ + /** + * :: flags says thatoptimization (any methodsof optimalization) should + * be enabled. If optimization methods needs to make some files and + * these files exists, enigne will just use it (do not refresh). + */ + ENGINE_CREATE = 0, + /** + * :: flags says that for this particular dictionary programm should + * disable optimization. + */ + ENGINE_NO, + /** + * :: the same flags as ENGINE_CREATE, but tells + * dict_eng_module_create() function that even if file (or any + * resources) for optimizatione methods exists, they should be + * recreated/refreshed. + */ + ENGINE_REFRESH +} EngineOptimizationFlag; +//------------------------------------------------------------------------------ +/** \brief Codes of possible errors which can occured while engine is working. + * + * - Enum type for errors' codes. One of this code is always in last error + * variable (variable 'last error' is invisible for programmers - they should + * use function engine_error() and optionally engine_error_message() to get know + * what kind of error occured). + */ +typedef enum +{ + /** + * :: there was no error - last action successed + */ + ENGINE_NO_ERROR = 0, + /** + * :: file, which engine tried to read, has wrong format or + * it is corrupted. + */ + ENGINE_WRONG_FILE, + /** + * :: user do not have permission to read/open file, which engine tried + * to open/read. + */ + ENGINE_COULDNT_READ, + /** + * :: file, on which engine tried to operate, do not exist + */ + ENGINE_NO_FILE, + /** + * :: while engine was working, "Out Of Memory" error occured + */ + ENGINE_OUT_OF_MEMORY +} +EngineStatus; +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//********************************************* DEFINITIONS OF CALLBACK'S TYPES: +//------------------------------------------------------------------------------ +/** \brief Type of callback functions for retrieving word list. + * + * Function which is set by dict_eng_set_callback() to signal + * ENGINE_WORD_LIST_SIGNAL should be exactly this type. + * + * @param list :: GArray* - there will be all found words in this array + * @param pattern :: gchar* - pattern to which we have been looking for + * word lists + * @param error :: EngineStatus - error code; if everything was ok it is + * ENGINE_NO_ERROR + * @param user_data :: gpointer - data set by user to be passing to each + * callback for ENGINE_WORD_LIST_SIGNAL signal + */ +typedef void (*cb_word_list)(GArray* list, + gchar* pattern, + gpointer user_data, + EngineStatus error); +//------------------------------------------------------------------------------ +/** \brief Type of callback functions for retrieving word's translation. + * + * Function which is set by dict_eng_set_callback() to signal + * ENGINE_WORD_TRANSLATION_SIGNAL should be exactly this type. + * + * @param translation :: gchar* - translation of word word + * @param word :: gchar* - word which translation we already retrieved + * @param error :: EngineStatus - error code; if everything was ok it is + * ENGINE_NO_ERROR + * @param user_data :: gpointer - data set by user to be passing to each + * callback for ENGINE_WORD_TRANSLATION_SIGNAL signal + */ +typedef void (*cb_word_translation)(gchar* translation, + gchar* word, + gpointer user_data, + EngineStatus error); +//------------------------------------------------------------------------------ +/** \brief Type of callback functions for updating progress bar. + * + * Function which is set by dict_eng_set_callback() to signal + * ENGINE_PROGRESS_OPTIMIZING_SIGNAL should be exactly this type. + * + * @param value :: double - current progres of process [0.0 - 1.0] + * @param user_data :: gpointer - data set by user to be passing to each + * callback for ENGINE_PROGRESS_OPTIMIZING_SIGNAL signal + * @param error :: EngineStatus - error code; if everything is ok it has + * ENGINE_NO_ERROR value + */ +typedef void (*cb_progress)(gdouble value, + gpointer user_data, + EngineStatus error); +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//**************************************** DEFINITIONS OF BASIC FUNCTIONS TYPES: +//------------------------------------------------------------------------------ +typedef struct _Engine Engine; +/** \brief Type of function getting some chars from engine. + * + * Function of this type should be used for functions which intention is to get + * some string from concrete dictionary. + * + * @param engine :: Engine* - pointer to engine on which this functions + * has to work + * @return gchar* :: chars which represents some information + * depends on concrete functions (e.g engine path etc.) + */ +typedef gchar* (*getting_char)(Engine* engine); +//------------------------------------------------------------------------------ +/** \brief Type of function getting boolean statement from engine. + * + * Function of this type should be used for functions which intention is to get + * boolean statement from concrete dictionary (e.g. to get know if engine has + * cache file - is optimized). + * + * @param engine :: Engine* - pointer to engine on which this functions + * has to work + * @return gboolean :: gboolean statement which gives programmers + * some information about state of dictionary/engine + */ +typedef gboolean (*getting_bool)(Engine* engine); +//------------------------------------------------------------------------------ +/** \brief Type of function which hasn't got to return any value. + * + * Function of this type should be used for functions which intention is only + * to do something on concrete dictionary (e.g. to make cache file etc). + * + * @param engine :: Engine* - pointer to engine on which this functions + * has to work + * @return nothing. Functions of this type should only perform some action - + * there is no result + */ +typedef void (*doing_only)(Engine* engine); +//------------------------------------------------------------------------------ +/** \brief Type of function which can find words list from dictionary. + * + * Function of this type should be used as a function for searching words list + * matching to pattern. + * + * @param engine :: Engine* - pointer to engine on which this functions + * has to work + * @param pattern :: gchar* - pointer to chars which describes pattern + * for searching words + * @return nothing. This function do not return anything - result should be + * retrieve by callbacks + */ +typedef void (*searching_word_list)(Engine* engine, gchar* pattern); +//------------------------------------------------------------------------------ +/** \brief Type of function which can find word's translation from dictionary. + * + * Functions of this type should be used as a function for searching word + * translation in concrete dictionary. + * + * @param engine :: Engine* - pointer to engine on which this functions + * has to work + * @param word :: gchar* - pointer to chars which tells what word's + * translation we are looking for + * @return nothing. This function do not return anything - result should be + * retrieve by callback + */ +typedef void (*searching_word_translation)(Engine* engine, gchar* word); +//------------------------------------------------------------------------------ +/** \brief Type of function which can trans. error code to descriptive message. + * + * Functions of this type should be used as translator from error code + * to meaningful message. + * + * @param error :: EngineStatus - error to which we want get description + * @return gchar* :: chars which describes us what kind of error + * occured (e.g. "Dictionary file has wrong file format or it is corrupted.") + */ +typedef gchar* (*error_to_message)(EngineStatus error); +//------------------------------------------------------------------------------ +/** \brief Type of function which should be used to set callbacks for signals. + * + * Functions of this type should be used as a setter for new callback + * functions + * + * @param engine :: Engine* - pointer to engine on which this functions + * has to work + * @param signal :: gchars* - pointer to chars which tell us what kind + * of event should new_functions handle (e.g. "word_list_found", + * "translation_found" etc.) + * @param c_handler :: gpointer - new callback function + * @param user_data :: gpointer - pointer do structure, which should be + * passed as a last argument when calling new mounted callback + * @return gpointer :: gpointer to previous callback. If NULL + * there could be some error so programmers should check by engine_error() + * function if there was some (if NULL and engine_error() return + * ENGINE_NO_ERROR that means that this callback was unused before). + * \sa ENGINE_WORD_LIST_SIGNAL :|: ENGINE_WORD_TRANSLATION_SIGNAL :|: + * dict_eng_set_callback() :|: cb_word_list :|: cb_word_translation + */ +typedef gpointer (*setting_callbacks)(Engine* engine, + gchar* signal, + gpointer c_handler, + gpointer user_data); +//------------------------------------------------------------------------------ +/** \brief Type of function which can get some int value from dictionary. + * + * Functions of this type should be used if programmer want to get some int + * value from dictionary. + * + * @param enigne :: Engine* - pointer to engine on which this functions + * has to work + * @return gint :: int value which user wanted to get from + * dictionary + */ +typedef gint (*getting_int)(Engine* engine); +//------------------------------------------------------------------------------ +typedef EngineStatus (*getting_status)(Engine* engine); +//------------------------------------------------------------------------------ +typedef void (*setting_progress_seed)(Engine* engine, + gchar* signal, + gdouble seed); +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//*********************************** DEFINITIONS OF ADDITIONAL FUNCTIONS TYPES: +//------------------------------------------------------------------------------ +/** \brief Additional functions type. + * + * Functions of this type should be used to check if dictionary in location + * could be handled by this engine. + * + * @param location :: gchar* - chars which describe location of + * dictionary to check + * @return gboolean :: statement telling us if this module could + * or could not handle dictionary under location. + */ +typedef gboolean (*checking_compatibiliti)(gchar* location); +//------------------------------------------------------------------------------ +/** \brief Additional functions type. + * + * Functions of this type should be used to get some descriptions from + * engine/module. Information retrievs by this kind of functions are global for + * module (e.g: description of handles fromat, description of module etc.). + * + * @return gchar* :: chars which we wanted + */ +typedef gchar* (*getting_chars_engine)(void); +//------------------------------------------------------------------------------ +/** \brief Additional functions type. + * + * Functions of this type should be used to opening dictionary. + * @param location :: gchar* - chars which describe where is the + * dictionary which we want to open + * @param flags :: EngineOptimizationFlag - flags to initialize/use + * optimization methods for opening dictionary. + * @return gpointer ::pointer to opened Engine. If NULL there was + * some error - programmers should check error type by calling + * engine_error() function. + */ +typedef Engine* (*creating_engine)(gchar* location, + EngineOptimizationFlag flags, + cb_progress progress_handler, + gpointer progress_data, + gdouble seed); +//------------------------------------------------------------------------------ +/** \brief General dictionary structure. + * + * This structure contains every data which are needed to make dictionary + * working. Data of dictionary are invisible for user of finnal module. User can + * operate on dictionary with functions to which there are pointers in this + * structure also. engine_data is for module programmer use only. Programmer of + * module can put there any data he want. He should not give end user any + * information about engine_data structure. + */ +struct _Engine +{ + void (*engine_set_auto_free)(Engine* engine, gboolean state); + + + /** \brief Getting location of dictionary. + * + * User can use this function if want to get location of concrete + * dictionary. + * \sa getting_char + */ + getting_char engine_location; + + /** \brief Getting information if this dictionary is cached. + * + * User can use this function if want to know is dictionary cached + * actually. + * \sa getting_bool + */ + getting_bool engine_is_optimized; + + /** \brief Making cache file for dictionary. + * + * User can use this function if want to make cache file for concrete + * dictionary. + * \sa doing_only + */ + doing_only engine_optimize; + + /** \brief Searching word list. + * + * User call this function to start searching for word list. + * \sa searching_word_list + */ + searching_word_list engine_search_word_list; + + /** \brief Searching word's translation. + * + * User call this function to start searching for word's translation. + * \sa searching_word_translation + */ + searching_word_translation engine_search_word_translation; + + /** \brief Searching word's translation (preformatted HTML). + * + * User call this function to start searching for word's translation. + * It differs from engine_search_word_translation that it returns + * preformatted string (HTML format). + * \sa searching_word_translation + */ + searching_word_translation engine_search_word_translation_extended; + + /** \brief Close dictionary. + * + * User call this if work with dictionary is finished and there is no + * need to keep this further working. + * \sa doing_only + */ + doing_only engine_close; + + /** \brief Functions return laste error which occured in dictionary. + * + * Programmer should use this function after each action to check if + * there was not any errors. + * \sa getting_int + */ + getting_status engine_error; + + /** \brief Tranlsate error code to meaningful message. + * + * Programmer can call this function if want to get meaningful message + * describes concrete error code + * \sa error_to_message + */ + error_to_message engine_error_message; + + /** \brief Function to setting any callback for this dictionary. + * + * This function can be used to set some callback function for concrete + * dictionary. Programmer should always set callback "word_list_found" + * and "word_translation_found". Developers of new modules should also + * define for what kind of event end user will be able to set callback. + */ + setting_callbacks engine_set_callback; + + + setting_progress_seed engine_set_progress_seed; + + /** \brief Module's private data area. Used only by module programmer. + * + * Here module programmer should keep their own data (e.g. some data for + * searching optimalization etc.). Programmer whose only using module, + * should not use engine_data at all. + */ + gpointer engine_data; +}; +//------------------------------------------------------------------------------ +/** \brief Structure that has pointers to helpfull functions for programmer. + * + * There are pointers to some functions in this structure. Programmer whom using + * module could use it to get some useful informationa about module (e.g: format + * handled by module, it's version etc.). The most important functions are: \n + * engine_check() - to check if this module can handle concrete location \n + * engine_open() - to open location + */ +typedef struct { + + /** \brief Function to check compatibility beetwen module and location. + * + * Helps programmer to check if this concrete module was designed to work + * with dictionary under location passed as a argument to this function. + * \sa checking_compatibiliti + */ + checking_compatibiliti engine_check; + + /** \brief Function to get some short description of module/engine. + * + * This function returns short description of module, to make possible + * displaying for end user what kind of module he is using. + * \sa getting_chars_engine + */ + getting_chars_engine engine_description; + + /** \brief Function to get module's format. + * + * This function returns format of dictionaries which this module handles + * \sa getting_chars_engine + */ + getting_chars_engine engine_format; + + /** \brief Function to get version of module. + * + * This functions return version of this module/engine. + * \sa getting_chars_engine + */ + getting_chars_engine engine_version; + + /** \brief Function to open/create new dictionary. + * + * This functions allow programmer to open/create module from concrete + * location. + * \sa creating_engine + */ + creating_engine engine_create; +} +EngineModule; +//------------------------------------------------------------------------------ +/** \brief Additional functions type. + * + * There should be in each module exactly one function of this type named: + * engine_global_functions. This function makes easier to load dynamically + * module. For doing this then you need only to mapped only this one function + * and the rest will be avaiable from returned structure EngineModule. + * + * @return EngineModule :: structure EngineModule from which you + * can call next functions + * \sa engine_global_functions() + */ +typedef EngineModule (*getting_additional)(void); +//------------------------------------------------------------------------------ +/** \brief Function that helps programmer to load basic functions from module. + * + * This function helps programmers to dynamically load module to their + * programms. Only this function needed to be mapped from *.so file. Rest of + * function are in returned structure EngineModule. User of module could mapped + * himslef others functions from concrete modules, but it is not recommended as + * far as developers of module could, in fact, give different names for + * functions. In structure EngineModule names will be always the same. \n + * NOTE for module developer: this function should be always defined in your + * code, to help next programmers whose will be using yours module in theirs own + * programms. + * + * @return EngineModule :: Structure EngineModule which members + * are functions for basic operations for this module + */ +extern EngineModule engine_global_functions(void); +//------------------------------------------------------------------------------ +#define dict_eng_get_global_functions(library, variable) \ + g_module_symbol ( (library), \ + _GLOBAL_FUNCTIONS_NAME_, \ + (gpointer)&(variable) \ + ) + +#ifdef __cplusplus +} +#endif // END OF: extern "C" { + +#endif // END OF: _DICTIONARY_ENGINE_BASE diff --git a/src/plugins/stardict/include/engine_stardict.h b/src/plugins/stardict/include/engine_stardict.h new file mode 100755 index 0000000..fe68b17 --- /dev/null +++ b/src/plugins/stardict/include/engine_stardict.h @@ -0,0 +1,324 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#ifndef _DICTIONARY_ENGINE_STARDICT +#define _DICTIONARY_ENGINE_STARDICT + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef NOLOGS + #define sd_timer timer +#else + #define sd_timer(flag,name) while(FALSE) +#endif + +//______________________________________________________________________________ +// ***************************************************************************** +//************************************************************* HEADERS SECTION: +//------------------------------------------------------------------------------ +// headers with unix types/functions - only for timers and files operations +#include +#include +#include +#include +#include +//------------------------------------------------------------------------------ +// header with GLIB definitions/functions/types +#include +//------------------------------------------------------------------------------ +// header with gnome-vfs - recommended I/O API for maemo +#include +//------------------------------------------------------------------------------ +// header with engine API +#include +//------------------------------------------------------------------------------ +// header with standard gzip support library +#include +//------------------------------------------------------------------------------ +// header with dict zip support library +//#include "dictzip.h" +#include +//#include "defs.h" +//------------------------------------------------------------------------------ +// headero for ntohl conversion - network byte order to local host order +#include +//------------------------------------------------------------------------------ +// header to g_memmove only +#include + +//______________________________________________________________________________ +// ***************************************************************************** +//********************************************************* DEFINITIONS SECTION: +//------------------------------------------------------------------------------ +// definitions for timer function - flag telling if we want to start or stop +// timing +#define TIMER_START TRUE +#define TIMER_STOP FALSE + +#define WORD_LIST_BUFFER_LENGTH 16*1024 + +#define _MIN(a,b) ((a)<(b))?(a):(b) +//------------------------------------------------------------------------------ +// definitions of version and format which engine handles +static const gchar* DIC_ENG_VERSION = "0.1"; +static const gchar* DIC_ENG_FORMAT = "StarDict"; +static const gchar* DIC_ENG_DESCRIPTION = "This module operates on StarDict dictionaries. Version 0.1."; + +//------------------------------------------------------------------------------ +// macro for "printing" gboolean statement - "TRUE" or "FALSE" +#define PRINT_STATE(state) ( (state) ? "TRUE" : "FALSE" ) +//------------------------------------------------------------------------------ + +#define ICON_PATH "/usr/share/pixmaps/stardict_icon.png" + +//______________________________________________________________________________ +// ***************************************************************************** +//****************************************** DATA STRUCTURE DEFINITIONS SECTION: +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +/** \brief Internal data structure for representing part of file. + */ +struct _FilePart { + guint offset; + guint length; +}; +typedef struct _FilePart FilePart; +//------------------------------------------------------------------------------ +/** \brief Internal data structure of XDXF Engine. + */ +struct _SDData { + GnomeVFSHandle* dictionary; + GnomeVFSHandle* index; + + gchar* dict_path; + gchar* ifo_file_name; + gchar* idx_file_name; + gboolean idx_compressed; + gchar* dic_file_name; + gboolean dic_compressed; + gchar* lang_from; + gchar* lang_to; + gchar* title; + gint word_count; + gint idx_file_length; + gchar* types; + gchar* icon; + + EngineStatus last_error; + gboolean auto_free; + + /* wrapper functions to access idx and dict files without checking + * it they are compressed or not - we decide about this while creating + * engine i function sd_engine_create()*/ + gpointer (*sd_open_idx)(gchar* filename); + //gpointer (*sd_open_dic)(gchar* filename); + gint (*sd_read_idx)(gpointer f, gchar* buffer, gint l); + //gint (*sd_read_dic)(gpointer f, gchar* buffer, gint l); + glong (*sd_seek_idx)(gpointer f, glong l, gchar from); + //glong (*sd_seek_dic)(gpointer f, glong l, gchar from); + void (*sd_close_idx)(gpointer f); + //void (*sd_close_dic)(gpointer f); + gchar* (*sd_read_dic_part)(FilePart* part, gchar* file); + gpointer idx_file; + + cb_progress cb_progress_caching; + gpointer cb_progress_caching_data; + gdouble cb_progress_caching_seed; + + cb_progress cb_progress_word_list; + gpointer cb_progress_word_list_data; + gdouble cb_progress_word_list_seed; + + cb_progress cb_progress_word_trans; + gpointer cb_progress_word_trans_data; + gdouble cb_progress_word_trans_seed; + + cb_word_list cb_search_word_list; + gpointer cb_search_word_list_data; + + cb_word_translation cb_search_word_trans; + gpointer cb_search_word_trans_data; +}; +typedef struct _SDData SDData; +//------------------------------------------------------------------------------ + + +//______________________________________________________________________________ +// ***************************************************************************** +//************************************************ ADDITIONAL FUNCTIONS SECTION: +//------------------------------------------------------------------------------ +// returning concrete part of file +//static gchar* read_file_part(FilePart* part, GnomeVFSHandle* file); +//------------------------------------------------------------------------------ +// convert string to proper path name (no filename, no "/" at the ned, file +// exist) +static gchar* string_to_path(gchar** string); +//------------------------------------------------------------------------------ +// fill out filenames of dictionary from directory in data->dict_path +gboolean sd_read_files_names(SDData* data); +//------------------------------------------------------------------------------ +// fill out few information from IFO file +gboolean sd_parse_ifo_file(SDData* data); +//------------------------------------------------------------------------------ +// parse concrete record from *.ifo files - used by sd_parse_ifo_file() function +void sd_parse_record(SDData* data,gchar* key, gchar* value); +//------------------------------------------------------------------------------ +// start/stop timers - return -1.0 if we start or seconds passed from start +// if we want to stop timer +static double timer(gboolean start, gchar* message); +//------------------------------------------------------------------------------ +// find proper FilePart structure for concrete word in dictionary +FilePart* sd_find_file_part(SDData* data, gchar* word); +//------------------------------------------------------------------------------ +// parse whole article to proper word translation +gchar* sd_parse_stardict_article(gchar* buf, + gchar* type, + guint length + ); +//------------------------------------------------------------------------------ +// find and return only one, next field from buffer and update length variable +gchar* sd_get_buffer_from_article(gchar** buffer, + guint* length + ); +//------------------------------------------------------------------------------ +// return size of files +//static guint64 get_file_size(GnomeVFSHandle* file); +//------------------------------------------------------------------------------ +// these are wrapper functions to acces different type of files: standard or +// compressed with gzip for *.idx or dictzip for *.dict files. + +#define _FILES_WRAPPER_BEG 'b' +#define _FILES_WRAPPER_CUR 'c' +#define _FILES_WRAPPER_END 'e' + +// standard +static gpointer sd_open(gchar* filename); +static gint sd_read(gpointer f, gchar* buffer, gint l); +static glong sd_seek(gpointer f, glong l, gchar from); +static void sd_close(gpointer f); +// gzipped +static gpointer sd_open_z(gchar* filename); +static gint sd_read_z(gpointer f, gchar* buffer, gint l); +static glong sd_seek_z(gpointer f, glong l, gchar from); +static void sd_close_z(gpointer f); +// files *.dict[.dz] +//------------------------------------------------------------------------------ +// read concrete file part from dictionary - *.dict* file +static gchar* sd_read_file_part_dz(FilePart* part, gchar* file); +static gchar* sd_read_file_part(FilePart* part, gchar* file); +//------------------------------------------------------------------------------ + + + + +//______________________________________________________________________________ +// ***************************************************************************** +//****************************************************** MAIN FUNCTIONS SECTION: +//------------------------------------------------------------------------------ +gboolean sd_engine_add_word(Engine* engine, + gchar* word, + gchar* translation); +//------------------------------------------------------------------------------ +gboolean sd_engine_remove_word(Engine* engine, + gchar* word); +//------------------------------------------------------------------------------ +gchar* sd_engine_get_lang_from(Engine* engine); +//------------------------------------------------------------------------------ +gchar* sd_engine_get_lang_to(Engine* engine); +//------------------------------------------------------------------------------ +gchar* sd_engine_get_title(Engine* engine); +//------------------------------------------------------------------------------ +gchar* sd_engine_get_icon_path(Engine* engine); +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_check(module,location) function +gboolean sd_engine_check(gchar* location); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_get_description(module) function +gchar* sd_engine_description(); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_get_format(module) function +gchar* sd_engine_format(); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_get_version(module) function +gchar* sd_engine_version(); +//------------------------------------------------------------------------------ +// implementation of dict_eng_module_create(module,location,flags) and +// dict_eng_module_create_ext(module,location,flags) functions +Engine* sd_engine_create(gchar* location, + EngineOptimizationFlag flags, + cb_progress progress_handler, + gpointer progress_data, + gdouble seed); +//------------------------------------------------------------------------------ +// implementation of dict_eng_destroy(engine) function +void sd_engine_close(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_get_location(engine) function +gchar* sd_engine_location(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_optimize(engine) function +void sd_engine_optimize(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_is_optimized( engine ) function +gboolean sd_engine_is_optimized(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_set_auto_free(engine, state) function +void sd_engine_set_auto_free(Engine* engine, gboolean state); +//------------------------------------------------------------------------------ +// implementation of dict_eng_set_callback(engine,signal,c_handler,data) +// function +gpointer sd_engine_set_callback(Engine* engine, + gchar* event, + gpointer c_handler, + gpointer user_data); +//------------------------------------------------------------------------------ +// implementation of dict_eng_set_progress_seed(engine, signal, val) function +void sd_engine_set_progress_seed(Engine* engine, + gchar* signal, + gdouble seed); +//------------------------------------------------------------------------------ +// implementation ofdict_eng_search_word_list(engine,pattern) function +void sd_engine_search_word_list(Engine* engine, + gchar* pattern, + gpointer cb_data); +//------------------------------------------------------------------------------ +// implementation of dict_eng_search_word_translation(engine,word) function +void sd_engine_search_word_translation(Engine* engine, + gchar* word, + gpointer cb_data); +//------------------------------------------------------------------------------ +// implementation of dict_eng_get_last_state(engine) function +EngineStatus sd_engine_status(Engine* engine); +//------------------------------------------------------------------------------ +// implementation of dict_eng_state_message(error) function +gchar* sd_engine_status_message(EngineStatus status); +//------------------------------------------------------------------------------ +// implementation of engine_global_functions(void) function +EngineModule engine_global_functions(); + +#ifdef __cplusplus +} +#endif +#endif /* #ifndef _DICTIONARY_ENGINE_STARDICT */ diff --git a/src/plugins/stardict/include/maa.h b/src/plugins/stardict/include/maa.h new file mode 100644 index 0000000..447b55f --- /dev/null +++ b/src/plugins/stardict/include/maa.h @@ -0,0 +1,603 @@ +/* maa.h -- Header file for visible libmaa functions + * Created: Sun Nov 19 13:21:21 1995 by faith@dict.org + * Revised: Sat Mar 30 11:54:49 2002 by faith@dict.org + * Copyright 1994-1998, 2002 Rickard E. Faith (faith@dict.org) + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: maa.h,v 1.42 2004/10/12 10:23:38 cheusov Exp $ + */ + +#ifndef _MAA_H_ +#define _MAA_H_ + +#include +#include + +#ifndef __GNUC__ +#define __inline__ +#define __attribute__(x) +#endif + + /* If MAA_MAGIC is non-zero, important + structures will be tagged with a magic + number which will be checked for + integrity at each access. This uses up + more memory, and is slightly slower, but + helps debugging quite a bit. */ +#ifndef MAA_MAGIC +#define MAA_MAGIC 1 +#endif + +#if MAA_MAGIC +#define HSH_MAGIC 0x01020304 +#define HSH_MAGIC_FREED 0x10203040 +#define SET_MAGIC 0x02030405 +#define SET_MAGIC_FREED 0x20304050 +#define LST_MAGIC 0x03040506 +#define LST_MAGIC_FREED 0x30405060 +#define MEM_STRINGS_MAGIC 0x23232323 +#define MEM_STRINGS_MAGIC_FREED 0x32323232 +#define MEM_OBJECTS_MAGIC 0x42424242 +#define MEM_OBJECTS_MAGIC_FREED 0x24242424 +#define ARG_MAGIC 0xfeedbead +#define ARG_MAGIC_FREED 0xefdeebda +#define PR_MAGIC 0x0bad7734 +#define PR_MAGIC_FREED 0xb0da7743 +#define SL_LIST_MAGIC 0xabcdef01 +#define SL_LIST_MAGIC_FREED 0xbadcfe10 +#define SL_ENTRY_MAGIC 0xacadfeed +#define SL_ENTRY_MAGIC_FREED 0xcadaefde +#endif + +/* version.c */ + +extern const char *maa_revision_string; + + +/* maa.c */ + +#define MAA_MEMORY (3<<30|1<<29) /* Print memory usage statistics at exit */ +#define MAA_TIME (3<<30|1<<28) /* Print timer information at exit */ +#define MAA_PR (3<<30|1<<27) /* Debug process routines */ +#define MAA_SL (3<<30|1<<26) /* Debug skip list routines */ +#define MAA_PARSE (3<<30|1<<25) /* Debug parsing */ +#define MAA_SRC (3<<30|1<<24) /* Source library */ + +extern void maa_init( const char *programName ); +extern void maa_shutdown( void ); +extern int maa_version_major( void ); +extern int maa_version_minor( void ); +extern const char *maa_version( void ); + +/* xmalloc.c */ + +#ifndef DMALLOC_FUNC_CHECK +extern __inline__ void *xmalloc( unsigned int size ); +extern __inline__ void *xcalloc( unsigned int num, unsigned int size ); +extern __inline__ void *xrealloc( void *pt, unsigned int size ); +extern __inline__ void xfree( void *pt ); +extern __inline__ char *xstrdup( const char *s ); +#endif + + +/* bit.c */ +extern __inline__ void bit_set( unsigned long *flags, int bit ); +extern __inline__ void bit_clr( unsigned long *flags, int bit ); +extern __inline__ int bit_tst( unsigned long *flags, int bit ); +extern __inline__ int bit_cnt( unsigned long *flags ); + +/* prime.c */ + +extern int prm_is_prime( unsigned int value ); +extern unsigned long prm_next_prime( unsigned int start ); + +/* hash.c */ + +typedef void *hsh_HashTable; +typedef void *hsh_Position; + +typedef struct hsh_Stats { + unsigned long size; /* Size of table */ + unsigned long resizings; /* Number of resizings */ + unsigned long entries; /* Total entries in table */ + unsigned long buckets_used; /* Number of hash buckets in use */ + unsigned long singletons; /* Number of length one lists */ + unsigned long maximum_length; /* Maximum list length */ + + unsigned long retrievals; /* Total number of retrievals */ + unsigned long hits; /* Number of retrievals from top of a list */ + unsigned long misses; /* Number of unsuccessful retrievals */ +} *hsh_Stats; + +extern hsh_HashTable hsh_create( unsigned long (*hash)( const void * ), + int (*compare)( const void *, + const void * ) ); +extern void hsh_destroy( hsh_HashTable table ); +extern int hsh_insert( hsh_HashTable table, + const void *key, + const void *datum ); +extern int hsh_delete( hsh_HashTable table, const void *key ); +extern const void *hsh_retrieve( hsh_HashTable table, const void *key ); +extern int hsh_iterate( hsh_HashTable table, + int (*iterator)( const void *key, + const void *datum ) ); +extern int hsh_iterate_arg( hsh_HashTable table, + int (*iterator)( const void *key, + const void *datum, + void *arg ), + void *arg ); +extern hsh_Stats hsh_get_stats( hsh_HashTable table ); +extern void hsh_print_stats( hsh_HashTable table, FILE *stream ); +extern unsigned long hsh_string_hash( const void *key ); +extern unsigned long hsh_pointer_hash( const void *key ); +extern int hsh_string_compare( const void *key1, const void *key2 ); +extern int hsh_pointer_compare( const void *key1, const void *key2 ); +extern void hsh_key_strings(hsh_HashTable); + +extern hsh_Position hsh_init_position( hsh_HashTable table ); +extern hsh_Position hsh_next_position( hsh_HashTable table, + hsh_Position position ); +extern void *hsh_get_position( hsh_Position position, void **key ); +extern int hsh_readonly( hsh_HashTable table, int flag ); + +#define HSH_POSITION_INIT(P,T) ((P)=hsh_init_position(T)) +#define HSH_POSITION_NEXT(P,T) ((P)=hsh_next_position(T,P)) +#define HSH_POSITION_OK(P) (P) +#define HSH_POSITION_GET(P,K,D) ((D)=hsh_get_position(P,&K)) + +/* iterate over all (key, datum) pairs, (K,D), in hash table T */ +#define HSH_ITERATE(T,P,K,D) \ + for (HSH_POSITION_INIT((P),(T)); \ + HSH_POSITION_OK(P) && (HSH_POSITION_GET((P),(K),(D)),1); \ + HSH_POSITION_NEXT((P),(T))) + +/* If the HSH_ITERATE loop is exited before all elements in the table are + seen, then HSH_ITERATE_END should be called. Calling this function + after complete loops does no harm. */ +#define HSH_ITERATE_END(T) hsh_readonly(T,0) + + +/* set.c */ + +typedef void *set_Set; +typedef void *set_Position; + +typedef struct set_Stats{ + unsigned long size; /* Size of table */ + unsigned long resizings; /* Number of resizings */ + unsigned long entries; /* Total entries in table */ + unsigned long buckets_used; /* Number of hash buckets in use */ + unsigned long singletons; /* Number of length one lists */ + unsigned long maximum_length; /* Maximum list length */ + + unsigned long retrievals; /* Total number of retrievals */ + unsigned long hits; /* Number of retrievals from top of a list */ + unsigned long misses; /* Number of unsuccessful retrievals */ +} *set_Stats; + +typedef unsigned long (*set_HashFunction)( const void * ); +typedef int (*set_CompareFunction)( const void *, const void * ); + +extern set_Set set_create( set_HashFunction hash, + set_CompareFunction compare ); +extern set_HashFunction set_get_hash( set_Set set ); +extern set_CompareFunction set_get_compare( set_Set set ); +extern void set_destroy( set_Set set ); +extern int set_insert( set_Set set, const void *elem ); +extern int set_delete( set_Set set, const void *elem ); +extern int set_member( set_Set set, const void *elem ); +extern int set_iterate( set_Set set, + int (*iterator)( const void *key ) ); +extern int set_iterate_arg( set_Set set, + int (*iterator)( const void *elem, + void *arg ), + void *arg ); +extern set_Set set_add( set_Set set1, set_Set set2 ); +extern set_Set set_del( set_Set set1, set_Set set2 ); +extern set_Set set_union( set_Set set1, set_Set set2 ); +extern set_Set set_inter( set_Set set1, set_Set set2 ); +extern set_Set set_diff( set_Set set1, set_Set set2 ); +extern int set_equal( set_Set set1, set_Set set2 ); +extern set_Stats set_get_stats( set_Set set ); +extern void set_print_stats( set_Set set, FILE *stream ); +extern int set_count( set_Set set ); +extern set_Position set_init_position( set_Set set ); +extern set_Position set_next_position( set_Set set, + set_Position position ); +extern void *set_get_position( set_Position position ); +extern int set_readonly( set_Set set, int flag ); + +#define SET_POSITION_INIT(P,S) ((P)=set_init_position(S)) +#define SET_POSITION_NEXT(P,S) ((P)=set_next_position(S,P)) +#define SET_POSITION_OK(P) (P) +#define SET_POSITION_GET(P,E) ((E)=set_get_position(P)) + +/* iterate over all entries E in set S */ +#define SET_ITERATE(S,P,E) \ + for (SET_POSITION_INIT((P),(S)); \ + SET_POSITION_OK(P) && (SET_POSITION_GET((P),(E)),1); \ + SET_POSITION_NEXT((P),(S))) + +/* If the SET_ITERATE loop is exited before all elements in the set are + seen, then SET_ITERATE_END should be called. Calling this function + after complete loops does no harm. */ +#define SET_ITERATE_END(S) set_readonly(S,0) + +/* stack.c */ + +typedef void *stk_Stack; + +extern stk_Stack stk_create( void ); +extern void stk_destroy( stk_Stack stack ); +extern void stk_push( stk_Stack stack, void *datum ); +extern void *stk_pop( stk_Stack stack ); +extern void *stk_top( stk_Stack stack ); + +/* list.c */ + +typedef void *lst_List; +typedef void *lst_Position; + +extern lst_List lst_create( void ); +extern void lst_destroy( lst_List list ); +extern void lst_append( lst_List list, const void *datum ); +extern void lst_push( lst_List list, const void *datum ); +extern void *lst_pop( lst_List list ); +extern void *lst_top( lst_List list ); +extern void *lst_nth_get( lst_List list, unsigned int n ); +extern void lst_nth_set( lst_List list, unsigned int n, + const void *datum ); +extern int lst_member( lst_List list, const void *datum ); +extern unsigned int lst_length( lst_List list ); +extern int lst_iterate( lst_List list, + int (*iterator)( const void *datum ) ); +extern int lst_iterate_arg( lst_List list, + int (*iterator)( const void *datum, + void *arg ), + void *arg ); +extern void lst_truncate( lst_List list, unsigned int length ); +extern void lst_truncate_position( lst_List list, + lst_Position position ); +extern lst_Position lst_init_position( lst_List list ); +extern lst_Position lst_last_position( lst_List list ); +extern lst_Position lst_next_position( lst_Position position ); +extern lst_Position lst_nth_position( lst_List list, unsigned int n ); +extern void *lst_get_position( lst_Position position ); +extern void lst_set_position( lst_Position position, + const void *datum ); +extern void lst_dump( lst_List list ); +extern void _lst_shutdown( void ); +extern long int lst_total_allocated( void ); + +#define LST_POSITION_INIT(P,L) ((P)=lst_init_position(L)) +#define LST_POSITION_NEXT(P) ((P)=lst_next_position(P)) +#define LST_POSITION_OK(P) (P) +#define LST_POSITION_GET(P,E) ((E)=lst_get_position(P)) + +/* iterate over all entries E in list L */ +#define LST_ITERATE(L,P,E) \ + for (LST_POSITION_INIT((P),(L)); \ + LST_POSITION_OK(P) && (LST_POSITION_GET((P),(E)),1); \ + LST_POSITION_NEXT(P)) + +/* iterate over all entries in lists L1 and L2 */ +#define LST_ITERATE2(L1,L2,P1,P2,E1,E2) \ + for (LST_POSITION_INIT((P1),(L1)), LST_POSITION_INIT((P2),(L2)); \ + LST_POSITION_OK(P1) && LST_POSITION_OK(P2) \ + && (LST_POSITION_GET((P1),(E1)),LST_POSITION_GET((P2),(E2)),1); \ + LST_POSITION_NEXT(P1), LST_POSITION_NEXT(P2)) + +/* error.c */ + +extern void err_set_program_name( const char *programName ); +extern const char *err_program_name( void ); +extern void err_fatal( const char *routine, const char *format, ... ) + __attribute__((noreturn,format(printf, 2, 3))); +extern void err_fatal_errno( const char *routine, + const char *format, ... ) + __attribute__((noreturn,format(printf, 2, 3))); + +extern void err_warning( const char *routine, const char *format, ... ) + __attribute__((format(printf, 2, 3))); + +extern void err_internal( const char *routine, const char *format, ... ) + __attribute__((noreturn,format(printf, 2, 3))); + +/* memory.c */ + +typedef void *mem_String; +typedef void *mem_Object; + +typedef struct mem_StringStats { + int count; /* Number of strings or objects */ + int bytes; /* Number of bytes allocated */ +} *mem_StringStats; + +typedef struct mem_ObjectStats { + int total; /* Total objects requested */ + int used; /* Total currently in use */ + int reused; /* Total reused */ + int size; /* Size of each object */ +} *mem_ObjectStats; + +extern mem_String mem_create_strings( void ); +extern void mem_destroy_strings( mem_String info ); +extern const char *mem_strcpy( mem_String info, const char *string ); +extern const char *mem_strncpy( mem_String info, + const char *string, + int len ); +extern void mem_grow( mem_String info, + const char *string, + int len ); +extern const char *mem_finish( mem_String info ); +extern mem_StringStats mem_get_string_stats( mem_String info ); +extern void mem_print_string_stats( mem_String info, FILE *stream ); + +extern mem_Object mem_create_objects( int size ); +extern void mem_destroy_objects( mem_Object info ); +extern void *mem_get_object( mem_Object info ); +extern void *mem_get_empty_object( mem_Object info ); +extern void mem_free_object( mem_Object info, void *obj ); +extern mem_ObjectStats mem_get_object_stats( mem_Object info ); +extern void mem_print_object_stats( mem_Object info, FILE *stream ); + +/* string.c */ + +typedef void *str_Pool; +typedef hsh_Position str_Position; + +typedef struct str_Stats { + int count; /* Number of strings created */ + int bytes; /* Number of bytes allocated */ + int retrievals; /* Total number of retrievals */ + int hits; /* Number of retrievals from top of a list */ + int misses; /* Number of unsuccessful retrievals */ +} *str_Stats; + +extern str_Pool str_pool_create( void ); +extern void str_pool_destroy( str_Pool pool ); +extern int str_pool_exists( str_Pool pool, const char *s ); +extern const char *str_pool_find( str_Pool pool, const char *s ); +extern const char *str_pool_copy( str_Pool pool, const char *s ); +extern const char *str_pool_copyn( str_Pool pool, const char *s, int length ); +extern void str_pool_grow( str_Pool pool, const char *s, int length ); +extern const char *str_pool_finish( str_Pool pool ); +extern str_Stats str_pool_get_stats( str_Pool pool ); +extern void str_pool_print_stats( str_Pool pool, FILE *stream ); + +extern str_Position str_pool_init_position( + str_Pool table ); +extern str_Position str_pool_next_position( + str_Pool table, + str_Position position ); +extern void str_pool_get_position( + str_Position position, + char const *const *key ); +#define str_pool_readonly(pool, flag) hsh_readonly ((pool), (flag)) + +extern int str_pool_iterate( + str_Pool pool, + int (*iterator)( const char *s ) ); +extern int str_pool_iterate_arg( + str_Pool pool, + int (*iterator)( const char *s, void *arg ), + void *arg ); + +#define STR_POSITION_INIT(P,T) ((P)=str_pool_init_position(T)) +#define STR_POSITION_NEXT(P,T) ((P)=str_pool_next_position(T,P)) +#define STR_POSITION_OK(P) (P) +#define STR_POSITION_GET(P,K) (str_pool_get_position(P,&K), K) + +/* iterate over all keys (K) in string pool T */ +#define STR_ITERATE(T,P,K) \ + for (STR_POSITION_INIT((P),(T)); \ + STR_POSITION_OK(P) && (STR_POSITION_GET((P),(K)),1); \ + STR_POSITION_NEXT((P),(T))) + +/* If the STR_ITERATE loop is exited before all elements in the table are + seen, then STR_ITERATE_END should be called. Calling this function + after complete loops does no harm. */ +#define STR_ITERATE_END(T) str_readonly(T,0) + +extern int str_exists( const char *s ); +extern const char *str_find( const char *s ); +extern const char *str_findn( const char *s, int length ); +extern const char *str_copy( const char *s ); +extern const char *str_copyn( const char *s, int length ); +extern void str_grow( const char *s, int length ); +extern const char *str_finish( void ); +extern const char *str_unique( const char *prefix ); +extern void str_destroy( void ); +extern str_Stats str_get_stats( void ); +extern void str_print_stats( FILE *stream ); + +/* debug.c */ + +typedef unsigned long int dbg_Type; + +extern void dbg_register( dbg_Type flag, const char *name ); +extern void _dbg_register( dbg_Type flag, const char *name ); +extern void dbg_destroy( void ); +extern void dbg_set( const char *name ); +extern void dbg_set_flag( dbg_Type flag ); +extern void dbg_unset_flag( dbg_Type flag ); +extern __inline__ int dbg_test( dbg_Type flag ); +extern void dbg_list( FILE *stream ); + +#define PRINTF(flag,arg) if (dbg_test(flag)) { log_info arg; } + +/* flags.c */ + +typedef unsigned long int flg_Type; + +extern void flg_register( flg_Type flag, const char *name ); +extern void flg_destroy( void ); +extern void flg_set( const char *name ); +extern __inline__ int flg_test( flg_Type flag ); +extern void flg_list( FILE *stream ); +extern const char *flg_name( flg_Type flag ); + +/* timer.c */ + +extern void tim_start( const char *name ); +extern void tim_stop( const char *name ); +extern void tim_reset( const char *name ); +extern double tim_get_real( const char *name ); +extern double tim_get_user( const char *name ); +extern double tim_get_system( const char *name ); +extern void tim_print_timer( FILE *str, const char *name ); +extern void tim_print_timers( FILE *str ); +extern void _tim_shutdown( void ); + +/* arg.c */ + +#define ARG_NO_ESCAPE 0x0001 /* Backslashed are not escape characters */ +#define ARG_NO_QUOTE 0x0002 /* Don't use quote marks for quoting */ + +typedef void *arg_List; + +extern arg_List arg_create( void ); +extern void arg_destroy( arg_List arg ); +extern arg_List arg_add( arg_List arg, const char *string ); +extern arg_List arg_addn( arg_List arg, const char *string, int length ); +extern void arg_grow( arg_List arg, const char *string, int length ); +extern arg_List arg_finish( arg_List arg ); +extern const char *arg_get( arg_List arg, int item ); +extern int arg_count( arg_List arg ); +extern void arg_get_vector( arg_List arg, int *argc, char ***argv ); +extern arg_List arg_argify( const char *string, int quoteStyle ); + +/* pr.c */ + +#define PR_USE_STDIN 0x00000001 +#define PR_USE_STDOUT 0x00000002 +#define PR_USE_STDERR 0x00000004 +#define PR_CREATE_STDIN 0x00000010 +#define PR_CREATE_STDOUT 0x00000020 +#define PR_CREATE_STDERR 0x00000040 +#define PR_STDERR_TO_STDOUT 0x00000100 + +extern int pr_open( const char *command, int flags, + int *infd, int *outfd, int *errfd ); +extern int pr_close_nowait( int fd ); +extern int pr_close( int fd ); +extern int pr_wait( int pid ); +extern void _pr_shutdown( void ); +extern int pr_spawn( const char *command ); +int pr_readwrite( int in, int out, + const char *inBuffer, int inLen, + char *outBuffer, int outMaxLen ); +int pr_filter( const char *command, + const char *inBuffer, int inLen, + char *outBuffer, int outMaxLen ); + +/* sl.c */ + +typedef void *sl_List; +typedef int (*sl_Iterator)( const void *datum ); +typedef int (*sl_IteratorArg)( const void *datum, void *arg ); + +extern sl_List sl_create( int (*compare)( const void *key1, + const void *key2 ), + const void *(*key)( const void *datum ), + const char *(*print)( const void *datum ) ); +extern void sl_destroy( sl_List list ); +extern void _sl_shutdown( void ); +extern void sl_insert( sl_List list, const void *datum ); +extern void sl_delete( sl_List list, const void *datum ); +extern const void *sl_find( sl_List list, const void *key ); +extern int sl_iterate( sl_List list, sl_Iterator f ); +extern int sl_iterate_arg( sl_List list, sl_IteratorArg f, void *arg ); +extern void _sl_dump( sl_List list ); + +/* text.c */ + +extern const char * txt_soundex( const char *string ); +extern void txt_soundex2( + const char *string, + char *result /* five chars */ ); + +/* base64.c */ + +extern const char *b64_encode( unsigned long val ); +extern unsigned long b64_decode( const char *val ); + +/* base26.c */ + +extern const char *b26_encode( unsigned long val ); +extern unsigned long b26_decode( const char *val ); + +/* source.c */ + +typedef void *src_Type; + +typedef struct src_Stats { + int lines_used; /* Lines used */ + int lines_allocated; /* Lines allocated */ + int lines_bytes; /* Bytes required to store lines */ + int tokens_total; /* Tokens used */ + int tokens_reused; /* Tokens reused */ + int tokens_size; /* Size of a token information object */ +} *src_Stats; + +extern void src_create( void ); +extern void src_destroy( void ); +extern const char *src_line( const char *line, int len ); +extern void src_new_file( const char *filename ); +extern void src_new_line( int line ); +extern void src_advance( int length ); +extern void src_cpp_line( const char *line, int length ); +extern src_Type src_get( int length ); +extern const char *src_filename( src_Type source ); +extern int src_linenumber( src_Type source ); +extern int src_offset( src_Type source ); +extern int src_length( src_Type source ); +extern const char *src_source_line( src_Type source ); +extern void src_parse_error( FILE *stream, src_Type source, + const char *message ); +extern void src_print_error( FILE *stream, src_Type source, + const char *format, ... ); +extern void src_print_message( FILE *str, src_Type source, + const char *format, ... ); +extern void src_print_line( FILE *stream, src_Type source ); +extern src_Stats src_get_stats( void ); +extern void src_print_stats( FILE *stream ); + +/* parse-concrete.c */ + +extern void prs_register_concrete( const char *symbol, + const char *concrete ); +extern const char *prs_concrete( const char *symbol ); +extern void _prs_shutdown( void ); + +/* log.c */ +#define LOG_OPTION_FULL 1 +#define LOG_OPTION_NO_FULL 2 + +extern void log_syslog( const char *ident ); +extern void log_set_facility( const char *facility ); +extern const char *log_get_facility( void ); +extern void log_option( int option ); +extern void log_file( const char *ident, const char *filename ); +extern void log_stream( const char *ident, FILE *stream ); +extern void log_close( void ); +extern void log_error_va( const char *routine, + const char *format, va_list ap ); +extern void log_error( const char *routine, const char *format, ... ); +extern void log_info_va( const char *format, va_list ap ); +extern void log_info( const char *format, ... ); + +#endif diff --git a/src/plugins/stardict/precompiled/arm/data.o b/src/plugins/stardict/precompiled/arm/data.o new file mode 100644 index 0000000000000000000000000000000000000000..312f733f341a173450874106c72c03fe06ca543e GIT binary patch literal 22016 zcmbVz4}4VBnfAFecXDS!2mzu-{@9BN7!Z<4h?Od}0RoB%5+Pu0p~ECINk%5gbY_B) z+8RwjM6s|^^=q-D*0yZ_?5C}3t)jKo?%G}4x~=_c-P(r46m;!=THUStYd_iNIp@8} zCEf0~-*#7*My3zJKP-KdXB5NB54Z z=z($coeYXn2#Ir%pfYIV||rmCIiL;;S1* z%i!0GUlzX(!tNdLYXJ6Qtb%SOx>fV=$q4ixJIC0m^=HV}JQh-F&f$>pK(42&b>P70bfw-1LqB6}l?;y+UOYVJ zK#%qhNdFjPZytlL^fgb~OrGDKIa9c=+2<4NoNK8!0#kfwg*~4BZNB>*{`=^?*kwE>>XiNR1PCwr! z)iSn9H3wH=u05NkV%n!WO?xW_Po~|yh)L77kJe1kGtN}$Iz>yfbzBi60;2WCw}oaTbZQqR5i z#SbGtql2S1baSnA1xy^$vrHVkwc^>te6pDTDl_&kXU@z~(5a%&jkl@;I^UVo%uhXU zYGA}t1EVcy!9Djb^44QGU+`&ACTl+AFV@GLvgiZjGcF5`1|pls z9LRY{=51K!Erj_bKlGf8A$M70x!)C_ee3(!M@( zr|{EGRdRUTZzts!34iGn{yNxS1pidc(eYsPbEj1F9_ZLSR)R4KdkXh=#@tp1#)}}= zLR?Vq#it>x$IRIIh{HEze?BgIyyth3I;__*;)qz&{=?(k+lpM%&ha6PPs{j$DdWkn zeaAc~*lEKij>UQ!3Da)aqZHNyWCm)7Mh>gN@gw-$Uotp8jF08shMKf#?DuERyuvw1 zAa^oDPo1^{|5etQz9@3%z2V8cVeF$rPlZ+VApF=oHcP1|ei=PGZd}W@I*3?(*4V8C zwf%d>!_htPVGr_2y+J<8gtkKZ*biPmee)E$Im-UcW7JWm_Dtkq2z0B&uSMb)bwzJI z=B{?n$o-1*I;qRTK4@dVV_du(^Kzav?SZeS-<=XBt|y)oPkV8BM%I&-eeG=IO0Wj@ zl&V8oA7WHk7CnSK$&HmYA36v1dybyZX3Ur8L;di{(h{tF*XS)otU}S}PKDf|kwToK ztmw1Y--l0fuTg3n*V#nAbcw$S_vm;+&&B=`ZF}^Hjum;EB{nOCcYF2l*a{zS1$mL@ zQFR3Kc4)lBy?5M28|Cn9$$WXu7l$02@UFKuE_>a2dBbQOV)Euglexkg6M$cpkQ>O{ ziv7!+n=7!6;LF6>wh-~DbRR$-9~ie*92jlI`m-_SA=~U(tU0U|6X$BRMf<-``iDx* zo;FZ%bbO$WxoG?^L9PUmE5Wxvb8sfkXw&e)-h}w6H+UXwmGLbyp1#`1*$VZ*ctOdn zBQ|vEdBR*&Jo5l-I&ta@#x*0a6xP$Zh^rO7ZL}G=yu#fxz7n5$e9G{dhff7Qm83Dp z#n`XjDnB|NaQBZ~D*G67F$CXVl=IR{a$fTC7U%zy8CgRvVwS0g-stej!@=N4L9~5j z9%95jfwffI`7ruaaKu4h8T$M&=6acj7~A0kr&+JV=>eDCMh}eI$am$UehnNP-->u! z&!FCBhEL**^oFw-_N>?xkU+^a}4J!+I>H2tHX6ZaL;)EGoKwVSa9Uj!CK^l z+JtkzdWAZf*9H?C$o;73-^pn@M4~Z zqqmK_Iu=_`En|5HG&LKaasmst$pP9GhL4kdP z8GI+5qqSdL+Rs6$P(UdH+BGf$m94MzWUkFPfR+r9h0$8PsN3JI?>f`&5RXJkCV znrW33%)XumD)fiHI4q7fMV%v<6 zW-nO;YiB}I*cd@cvqS_0D>d5;QL0pI3K^Tu(K3-c=gMF)v#feZ zEelOJ5de8UNYP1hPTg6(b4jkBU01}uc@+7l0_TIrC*gug2}*rnzEz_&E9Hh%&1{NU zz#FA5^cfhUfi415F2-q>E9OI=H+@&}0x6i`T-pL~IuF z;z<`iQna#2sipn~3RaKdRASD5wobQ$IPLPP1!a8=OX>Gmf`QH0H*6;`08T3$ScO>% zIDu~Tps@v%RS>ulEP+rk)st6tDDVy%!=b=J)RC}be+_-k<*4Dxp2ypj+j)BeqgL4kp-Q zY_?zH$ot4+?_lRw^zATPzs}o`?ZDN*UtzozwqHg|LDLAoSED(BB^@rf(Fwznf_^p! z%9Zm&Qa5R}<+ch#?M4oG6*6Ciiu=P?M1GBiNRh>MjEHn$L}aFZ5g91ABfo;O$Sfhl zk$W*Hg4IAf%8Md1ASY5PWJ%gEb={yI#0-Xk$(1;3F$_@g|l^J zj*u0RR+=$a$jZoD@Gde>$fc1T4#*3v)ff{fk4A2yUe~%xlXVf7k}njGRzx17s6|4q zjC`ABR9eTu6ezEctYq&}Yq=&HB6niaBg?E+np_tdqNpnC8ZG%s#06xn^>IyJ6?ur! zxZL^&&Dr~0I2(cT*2w$dimVoLTjV=rZV)qepn`#1XC<_#gt8aGhoZMRHe~+` z?h85B_BM2ftFG3q?3?x-y83VdJwG3g6h$6$KE&93$HYQ8cs@~)$4w|~CqGNl%5^DMd zl0FV2HT?sIvYkhue!5E;f%34jIb!;PJ3-pD1#^BZ;F z7JL`?;%m~u857EteJy&X5AD{h17v;bY*wvN+c{}0S&Z2~;N43e2~#OKWd8^)A^XSp zF68)-jpti@kFbGaX5k&W3WcntysxC^joJ5iRBUm(pYs)CPzqYa-G z_9mwfE%s)%u&9J#irqpvs1QywjIp=;A5DdwjaW|hb%wLZIggyJhO@+(!M^JaXX(uD zT&J=>W@<&5gEynd_PEwC&pAPvAIGi*4X!f-vh5gs36xhjRp7CA(8fS{rE@FRtKG)P z1*!dLu`V3X1YzheO`V>SJuvD%X(Babs8;78QhN-w&3S?L?k$G9f$|+rGxP>; zH+_kjy*U-!XNWH6G7h`LP-*9U4%=_2jAPTVI}Me0*2CxEU0m6L@_y$v#5#C@u?Upk z>^wv2Zn_XGAF!N*Wc`dGhpd_H*>)8?Naus)`z+@-yg6jZyDVn`=j1O8dC+pIY0y2Z zX-N5D3scLUqD`PVk-FyD%H{+F55K_qIE}6c@TmyitIJmKK2AH+{V^)~9JfrS`==P# zBPU=fN}BTx`u0Er+BhM1LQwDvtSEu<5~qmX9A$M5l$Sbh(!OCwQ)LbpNbrj+T!Hd= zPM&>V(wlp^t8AJP{PK2ummY!}-QcRUgJ0EYa?He0IXX@L(oDCc$=3`eY4UY?Osh6B zp5LG(TGdACnr)#E`>bXD7*Tvtk9y9}26Y z2O*O>&(T|mrEHoSeDobyUhq{ME$;w%SMV|CApQG}u}(S1=-%UExidiOyPoA~TK9yZ zikuf1!6yw>;=D^!j~lAg`84~UGE|v!g7fgSq2@Vd?E9XfT<2eD^)rU5m>F+RtKj#u z@RQ}EmHs|!V!G7K`*XA$rwS*+6#C&eHB|@Qp#H{CE1W)B{kMi%>D*7teq?gG-uW0g z|Nh&0T!ZriQZJb5aFtU*eLpt(nw%bv`$t1HJO6`yKQUB`)5=Kv)KIO?YTELWp|&{} zk@}gTb~yJ@!_N(saGvG3Ul?z@oIlXcUm7ay{FKzM4V7_DaNLNY^3GN4JNaF0b-(ik zPULH*?`G!-Qsboby8J7Wr@jZ)VEK^ctfrjPhTO-c##I)wnH(XTfezVRTp|0LXt9|S z!Pj|Punx!kzr<9{3!aJG&JLNP#LwYYnf}g8vWPy++ z=O&UJDj3lR0xZ19KQS2!^%jp(2s4_Xqwt5YeioGnr&%xJzMvHcvR=qNB%AAAH zRTw>}sd>)5?5i;vT!$yc!dj!D(ovLBXU?Zfodl^B|E$MFoulNu{NFTH=UjjpDO`6x zI0EG>ocq{!rJ?Gb?{M5zhPul69O7NL#Z-i5=UtB5YN!@<-cR7V6~}0+R)-1F)l2wT z+socUB&;aoZnd7DPWFIcnp@YEh2Vh|W!70+%eefk8YYOfWzI4Z%k`L+IqxD|R-IFuh*W(gZNK59;oT1bSO21lLLrY$!8QaUa#aUNrHP@FNpyc&j ztT2E-3|Q;6n%4Qbd{$YF6k}aCKb5FaR+H{&0a5D_&GU09Ur#PI*)vCbz2Q6v2p)P_ z&B-z}*BB8OTtZVcF+YWaqi)?YKa*EhvvGNTyRxp;%}~*%tWDdQ(}&c2?qAksMjb)o z!N6+KY@6r&RtHY^Y|=rhoPpj@uoS!>Scdxn#C#YZx1JrF7c>F5qTa#4A~JLD&{g=% zMJ9?DUQfzXlLIw&W7jTpsat@EXJWCJgdW@N(`zPgPxh7U8suUv!DXR zf+)U>v(KaLWwz5dj+JbA`%le%ut0CS@|A0zCyVl zM|}cP?h0n*_QeTI|8`x(tZj=EHGs8#k57p+i&!Q>>Ac#yh)-r7)w1YP8t`dT zBo9?C`gb~DNc+&s1NIWV1O~K$fkPD+F~1FEU4Ielt#zxBd)*S9$+v0a1BaF_;c3_! zG@i9C(Y0X6qQ!wj(IsnW!ye&vm*CZtM_M0Satl}1Ug?~-WDincf-K|A+-@SY^&%vf z+;3X)8Y{&<)3a^KKQJmnUAN?1M9-tHUBZ*Ob%*9O^+!i~kiiTEw}Dm9_&!6Y8Tlf1 zPAo0F0M%2jzb^h2G==ZxbGBt&%x8@7XAH6QO6s{-C%@D=&Q(DD91;W8ABv}A1QSIu z=GA?8c`R_AWYDSyLRM0Hy#pHt~nTX#H;*FEukysDi>=JN4;6{a0+$&MWE zaP0;g?x1#edv8yNxy`4#lX7=cCP_{hpUWpwy`~joyjzipekemPJW8b6^Ub)$#oI(C z-Pf7wF%8I3s6y7(Sg&+;z0>%M!KUzq(dwszk>5S|^QSr+n>w31?LhGUz}20$6@2|u zUpU&?*w|SeUJ$ORZft7m?Cd;x^k`=na1fm68g6{B^C-R>n}!AlAK%-xw{h8q=wNtv zW9RV=zFV-So($Iy>fsQP8hW}hzQ3_L{IMr%tC!VuQR&<2>RX}oo?D(czTwHIpVTc+ zn3k)LHw}juG=6{Z$)_7P40SeES1;+t*gYFMhaq`qXYJrn=iv9M2bb;~eC5H;Wi_1} zF0S6#+1c3D6#j7dqp$ovSQK`nUEveq55N1+(atCZ=gwuXaaChyXVcMeMR>vS>dxxMqfd4|{p8DE>}>pb)00mfA8s7%3V(Aj z_}DF12VYPfjnOX!>X0xd>M>4xtRt1qC$rv6#InhFBG!d3Uz_IZ&0xdUvt`D$r+afr zAKlxQkEg)l=h4D^JceGUHM*VIvm*&yWNEeHxtk0-E^uum3MnP(7-pf zswvsineTFMjOWm@)a~iL(M|D|oiuz+yr-uZ17M&_Q(d@}bT3?(yU^|E&AL>o z(s2ZdGL|iKQ=L7%*;G#_ozh;C4ff@e{fI(V?Ci~U$Mf3nKOdh$FLqp_Q(`yK*WDe@ z{JB2H_Rsa@y80lq_r@OB){%~D$KhwHCwZB>FbB)9p((HOB--3%S7=F7^QY2Xm|5x~ zVBS{_H#rwU>S6>dD|hv#67G`4(ZvYIgg?pTP8WgB^ktK7r=B+*4;{l?RpFK#W+RP! zH9@Ono@A0)KzF>SJ-K*F7+uYf%f#E0ZZ5tHvCl28(y^_ns;%NtTVkB*!34+Csolvx zcBHbo{F<)5o}Fw!p6iB<9UZx(=0-~ztHaMh+Q&eHx|Uth zP8qq6Elh0Jg4`>pD&bac+|m+Ty=C3HwVPs_*MD>^vrH*7HQtO&&~5@TWmD+;-SkFBsxAWLZ zU=@xg_+9V}eg?E|E-sp`TpB7D&+iSz^BRgP@3!^__62XZ_lEWq3^_at@?yV@t-qnz zZ73dTZYX}QnT&S?_u03H_7?1MhQbQJvFeLQ(v{e18j4FBiu=j7H@L?h3YAGe&vm7! zl?}xu?A#L^vM0v!Tvnp{FxH(MyHv*V5Y>tUNkef(L-9icc0)1FL3dks2KEQD+Yoq7VN13or#KRl~4$8b2EY}93#N7czDQ;9!&R-07gFiw7xjHdj4 z6^gi~W8J-pq&AlUF-Bl(mWwAq?@IL~lKrt9N_DDV#rk^sa!EY;F#9&=JtW!F ztNPaCM=&h)&R9I1Ztsd`b1D|g#PeOM8>fX>PcNZiwL+cB#@B%_r*@^X`M!8MmS~Hm zQ@OlK<@73xr+fOkRc!sn7&eF)kBG5c7YZ~emCog3P2|N1CEl0L$MA#}&nG)?()>4O zQ~9JG(G~AWq?7tYlT`6^rYqi-%qw%!&;eFF!^HA1Uz=izFf8uv=s+uqbsm0kZ-l}e zmbB7oAHyaWOZT?#6tcH3uiAUNGudPgVUZNS@|rE~8h3eBT~(c1nN6mX@f?aufkY8O*STY9Hf!(yyw4MFM1CX=ytgfp4YwXzL@CT^~Y zchkREPde4J(>KpD`RHkfi@pw%DSb`Y+|E+Kg{O4g@S2m^Y;RV_06Q0BKo|S+$u*nS z_``N+6O`6R->{b4ODj`5n?+3(Z@q8rZgtm zfZ0dI1#R;D5}&&nyb7Q*GA{~qE*T=N7-%dKnv2ymOjdWL=Xf`>HW}|$>()1|^+ibJ z=@lZmq*otp5J@L=3^;M6u_qe{l~4B@oUIWbs^o1n0UOl}*u zjR^Rs=iiHNCXVIa9q$)|b~7olqM$R@(bvwzQMPL`U< zqB9Y$c(%REXkqkonPj{6VLb~D#<95gLaFZ?LZgpj8(@CS}S}Kjcm%3wm zDekO8F2o>BRR=aJRvA_pCXS9C3lGvmFLCawYq+B!HJUfAZE3kawr&Gibj`C>{^C{Nen=wUGCt)1bGOKu+%Am;d{HwocEI!F> z56U!4Q_^&@ohEe0vpX>^)#FWiZzleUKGdbYHpv$;$rK+d=G1ZKbUlqTQM~04!!s#0 zpA{})|*avA)%F+R?&R+l|NQe75?=E^I2fd~bGVbvCI_@mNyHT=jKq->lp7S>y+p<5{{}%_WyY#HzLP z%WA4>qE)q~#OCnekVh{4}lhI!l)TbPJ>rLJ7F<}$Yur;)|~ zPlu6J7vSg@PsZEuo{X=JLpZC{L|Ym*tXBm={9s>|yQv#?0P|UcUEUoIJ5_uTRaH6( ztJ-oo+$P)la42kR%VO16k;Sy&>7&h@ZIzL-SmWKnMoJ^lC?$9(T zJD!dAbS5X1LyD^M7ETrXsfy?G*;E_OG&%2_``^G1fCtBZg+~W{)#2NJRQ3+gbJ32+ zhl%UqbxQ5S^MHPdh*t82@mYuu<>BR+zMjLe+mpct@BU)kli%Ze{?G75!9#i8MZW9J z*m5w9ebG=Tq@s|Dg{~nD1eI3Vx z+M6B$^oI1|-f!PN*tY|1w66#s^3l%y`1t)jwoIu#X!9Uw?+dv1 z#!$wxDy3ZB$mR8Y4zyq1Tabq-*7gxSdEdl6$1opwZGgP*`UbL(pT`9O`YOPW6Z-cF zp*_9d2aVjzNVB>EOk4}z`)K|E@ve_<)gX&j``?=pr7;6w1@9^%w_C(Yhsct zbuT)Y=gcwA$CrU4Q^xcCkGahFvWaQ4)Ys8*6+T|PzmNOyL|#r)e+#c-(VVMo6KOq7EdhO(kB)*q;-fzZnt#@0u4!r|=+i!0|NSS8*O$p}zB4nI ziN^{$uP+StT|r%mCmVu_m2~n7>Zti?-^PaKpu%S7yMkCbSBVOmG!q<~gl109LU7xC zCeW;%Q|P`a^et29y;JDPTsCw3*(v>Bm_k1~g??fR{mc~l#VPbJrqH8P=+~#vzneny zCtdHN|K9&-u#GhTWWu{hPn$xQO`-Y6Cf-HYb z3LTq5C#KLhfcD=1QvdEL{kKk`?*i?;6DI!yQ~LQglioXF_CGnL|3_2kpHHFnBLJT4 zD)5fN_xMp2RaH%E^jD3lh@ah8!@gR6E$0`G&`oPD;nxTGb*Xv4)Nc^v&DdFz^}rS6 z{1Crtj1n!gM)%b$KUQX&i z8&jjLsnyoh8V|KK_=6{?sMU&UwW3VGCH?x%SE8*m#@7LORndv(Mm)mAu58-4dR0?w z>M(CmD9U>wgU5IL(nV=$DCx*2(`hrU`iW6%hUw;grV-20H^#F)_$f!3e*6@Gr)elL z;`s<{;$rCTz8-SO4@GNX(j2hXs!bJ}SsPnS3t`zAK0=Nw=2@&J(N`iM9d@PD()N|8Urb1?5jJp9@C z`yt9JCF0?9DKQ2;#2ttS5pfzO#vzx8JbQ_VJbG8?Xc%-G@`H%}ZA8e;6Wbw2+K&(u zh%b*=82u;8P_PS{Pvyu2yxVXQ6sT|&e-t~J^<4@iA3u&f;OL9D<$13CZwMEJLlxE}E( zrr?KQDb9RzZ@_pUE-^BwC z`CEx-&j@`)aD)gu-x8XCtw=dM>(c*~z_KXn6R`%*!o
i^OGEPsA$BC$ScKh|4jr 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 PBIRg~3gOFQjrjR*t|I)K literal 0 HcmV?d00001 diff --git a/src/plugins/stardict/precompiled/arm/error.o b/src/plugins/stardict/precompiled/arm/error.o new file mode 100644 index 0000000000000000000000000000000000000000..dd327e7acbf333716bbd78c329fcf1e6f6c93b35 GIT binary patch literal 8352 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 literal 0 HcmV?d00001 diff --git a/src/plugins/stardict/precompiled/arm/hash.o b/src/plugins/stardict/precompiled/arm/hash.o new file mode 100644 index 0000000000000000000000000000000000000000..4468a938766832d5130629331c05cb6537aa61cb GIT binary patch literal 19680 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 literal 0 HcmV?d00001 diff --git a/src/plugins/stardict/precompiled/arm/log.o b/src/plugins/stardict/precompiled/arm/log.o new file mode 100644 index 0000000000000000000000000000000000000000..5ab420d41ff049fd5f7502e772d724d794cc8b55 GIT binary patch literal 15428 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 A00000 literal 0 HcmV?d00001 diff --git a/src/plugins/stardict/precompiled/arm/prime.o b/src/plugins/stardict/precompiled/arm/prime.o new file mode 100644 index 0000000000000000000000000000000000000000..38d26a52b022f7f93ee976bd8593c24e637aef6f GIT binary patch literal 4372 zcmb7HU2Ggz6+U-n*R%1if09i?)P!`4lj5Y#u46kf(J^)kAy@E2sLpZ(jp-tRQ|zy-<><_ zbzXog&3xxO=iGDeIp^-o?1g*oKdzLLcqkc^6(;iL8f{68X&97^l9k5zuD4};@wz>= zxU}Z6#U)FomXs{ojf=0OY&qSQm8`!(oh9;)ntI|!(tYwxVnQCdo)FoYkj3lC{>AJ6 zUS9sa$Oo3*U0%NJ7TpcR%_7Fleypj+FD_vl?^xrP5F?&9wepeCyiF%>?^F=L-uy^Vd$OHt-uQer+wC@H_I5BL(Je9If0xZXV3x2R2 zp|Z=y(qbj;KLJun`$GgL@fErpc$7i*!!2>;;}GqiQJYLWPt7y)&?FOIp#C-7RH|!~ z;c-1{<(;$CXVi9pH6YHfNY|>*Xqs>u@Uqt#nsT0{HEU?bd5d(tq5aMfoi`Y|-nom` zjfQS=UZM3phHi0gr*)H|IcF3*wr?|ZoAWrWn++XwzDl~q&>`nJI&W1WB3c8(&W~u# zsq>nSInR*3&t$aE`54!|)6j#?pE-9>Ex^ed7n`=6rpFzC*m-q9 zM?T^Fj@A)%Mbmqor)WK(2-d)qbCuQ!rHec8LFYx%BZhw1`30SinQc7ge242ESD)3P z%92W~Sx<*=cQL7J5Ht2m-Jhq^ccV0=`%bd&MOh}gkJJ6-sBJ0q_aLmv#3Hn5?vL%x zjN(S^9w^c;bZSSX=O(!N8gD!GuISptr5^45G_^a1NKW^qN$%3*;l3BC8`9(v>Dh{d zu3Xv=t9#9K9(IIy9oefx+HtBcOPBE|p7j41ChIcuP^$kvxLa2uA{R;IBfP7B^!C86 zA9oB@XoW$+uT584WluUuq2xD1kw)NGz5Fz$O4uy>_52*4jTOHXi_P;5FN7A$q9pom z?@;#@hG%E}LgC#njqQHjO6Z?x1`f*@O4LVtGd;42Gt6Ltj`j9mR!>?_*q0K*rg2a| zi0fEy>ax0I$p~b&s;O&hX-jfoT~@T zQfo%EkmDnyIQd|)QlFkLMk0(wuU6LTbAjLVG;7sDf41h8qZy5Q$RgES&34%;_1bJs z-&VWMRNUE62P?VL^Q}g)oYTu%z&=y z2J>DZ#pyZMuLw1^+0Z9czDm*(On}ubU3{k9j!1|uX=^B85GXVp*CT&9?Ta44+Zfd z`d(N#L;XWq-wax{c{sa4*`IC}V4wACZlyq0-nBcwdpJK*zzM6mE)vnnp;SdATxK(h z4Y#~If)Ob$G~H6giwnmiS`(cc)8ZPK!8S(9)lH~Z%JD>2=lJCP_ej}a@WXl_JVDZS zkBS=dgsjw2SCs*FUw`nlu(YUjjO{0v;rE%~DO+e@O`yN6F7 zdtg$!?39vxc)p5C1DipFbFqZul5etF`Lf$|C0`0dh+e5RTXajMz*~?!T_TNNo2hs5 zieK|O`ApzeS1B5;QVlAETnXX^Zf%yTC?+-{`RRJK>Y>tkY&`Ean}J_y;UMzY{l5;r zIq__hE;C^a*!h%*pB`_f==S-y&WPI>zHSTO5x~?u>U8 z@%BO&kJwg+qBGtJ#$E=G?d({fG$EP9k zu?5ZO7i*-0tNRZ=Og*^nH@H4GxWyQsoBsfF3WFX1 literal 0 HcmV?d00001 diff --git a/src/plugins/stardict/precompiled/arm/stack.o b/src/plugins/stardict/precompiled/arm/stack.o new file mode 100644 index 0000000000000000000000000000000000000000..d7c4867b27c0be04b3909927bc22b9e7b3f97746 GIT binary patch literal 6904 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 l=na%BCXR&GD*hHPnelN z3+!5Hz)~rcrFfJT5|0Hrf_p$k*+W??^a!3s1x4ko$hL(Xs+P3~uCA=I&vWm4XTA(| z*ZmI7^S!_Kec$`@-Fp*0wY+nM<2cGbj+(8?lu{>VXi1<=!)(={rmD!|dB1Yi*z13J z|NY;n#bd`bs*!O8o{AVc06L(?jzxAoeIn96?^l5r*BswGHab3O?5?A2GjvTY3s#($0H+8pXjzp00T$o zjkC>wGB#-MxTD7E0?<{6X$Uzu+Ym?B*s+q1#DzR25AAxoL8*Jkt0W)B8~_~v9f;Z- z$Bscy`*P71{RO)Aj|Y|11UAgGhPiO&Qt8(e*gV* zSW_16oxZIpr)i5hd|28;Z6~oU^poyCwEsHV|MltGKPl~p(f%p4 zUs+RI%m0h7bC$YWT_yce>EmzZ$1tX@m@uC9kH=)JI8hm!GEPh%9~cj!4#B9YG4qXK z%q);G!||X{(|XiH_dyr?Zqw_mr&6EOhG&Sl>?WeY^+Mh_si ziSvx(UXT(L`TPc z3b{ojU+C70Ze<(no1@63p7nr@olBK%)Eq{gU&VU#Sm*Ih+t#+RV-D(kX6)0)t7Ff; zUh`t_(Hi)B0sd;#*fGu@J8sy2!PpPpwC&VLY)vnA93Oi0{u8VIm-wFi8{$)_L6eOO zv0^MAi%3pkPaUv0>4)>6+3F)^=J7y9J2rNX_o&#hoqDnR2k3{T4Lz=)7ZE*gy|&qQ zwweCOt6j&d)nU|Yo32-T*XVdKdf%JA7~{U>crc1SR+wiIvxZk87t{CBpI94zhc$*e z( zr5ehODRuT#gv3zvSC7ybLQSWj!cCqif)|8s6z575NRTZ}7uQ0b*CGWh8$>7iDQ7)H zf)vval|3mnvqedv&~(|P*~_*O%_=9fD0~IS(>!zp_Aqz?94hKvd{p^-2~6i3ex;7# z#h1z!RUqi^fgn(AVH&>4j_bc0;H&ok47!lrN@kUR1~h#^|8^L=L4Odg-Ri(Hs01(H zN+)-M_?3~BBblyLghLk!|oO;*9#eOFQoERA?sak z%mUMdY;Zq{5Cdlk+2nG`3^WKCb$>!v=Lp&CwzHu|A!obaAlW43Tz4Upp6=WZ8{f>B z`*TX8&Rv>pbGMNEkYu#LeTPwO3EIwfuGa}JcEgNnuCqjw?e51Zo#(98xwA(rce$OEE^$~~-^|VK29isK+~U4R<#q{Uo7={A zS2&Mo#=Gkbr`zgz_&sTRQk3_Q-zwD$de|^K{& zC*}msD{u>NXfU;P)(tG7{-l; zimCv^@ZB^3W-#y)oYa1Wwx+;mJ_z=o@z3?OJMM2OST40yE-2+&A!I<+QqQ;2d0czi ziJ!Iiku#wCruG2i8+5)0ICD1QX+pF0zE6tR?GwGGtyfnkk`dB%btYLM!> uBs` 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 Q(jS%)g+HGvVMOZqKaUedOaK4? literal 0 HcmV?d00001 diff --git a/src/plugins/stardict/precompiled/arm/xmalloc.o b/src/plugins/stardict/precompiled/arm/xmalloc.o new file mode 100644 index 0000000000000000000000000000000000000000..d35c9a06438966f164b5761bbe25870d3ce7b661 GIT binary patch literal 6568 zcmcIoeT-aH6+ds@%%;ua#f}w22sjM7stwHKM_g0MU|w8bt#U<3}4Mp`eWz4N+9UV64C2efQ41 zZZP5>-el%?&pE$y?z#7#d*7S+#PHaNWm#gHB|XxRM7BnhCD^Z^M>?fLT8B3OA^76n zS5u3pE-YU>ab9*VzVfe&7yl?S@!OEdnssvOg2?gnovo)XSgps;2jiYS_~N~%^W?q;N)?&Gu8}e?|xrB8t)W>~u zp>JIKn)MLO;obb!`TVRltF@^e-`$aDiyc{uB@c9o?Xc;Zv&+83w|1;0+s$wSbD zf)7&vYkXNwDEKvC6E)4(gR%yn2LcJ_E>gl)Hz2TH9GnZW+pNzkG3b06EW2Hcj`K}g zqgo6*Z%~YBvDNt?$sJmZIooMnrNvI?46UoRxX!tP)=n+PodG0ouhC+cb1$uHwb>4=Hhv^CeohTX!q+g!3I*2P`gbVErx5 zvlMq}@mA+$l81B}w>gh<+!1S0k*8%@aCwY`$C^2*=g@$^5v_E4JW^+MQ5@AM)>$NJZBR+tD?b9V)y+$* zb-pUr)tpJ&P563)R0$JUL@I8xG%-SZmo383Y-9LX2czF3eKPg}VIp=G5CRD;k^x#b zk(Khs>?qa>VkJ4IH@xbq;d|@DD=$6VLx{j3In@0ObTE1?gHA>V2nS+ggo)TqfRL>= zFmjfvVPmC2xm^dN z35bZk6%ex3MIHGTRj<=LrjCi-Q4#Ayi||p4xt9l8?WH2>#XJuuhG$sbR|tKQaVBC9 zdhjqHg!>(B^~)dx?qm5`*6Jx}0w+8{)B%v&sIuOPtbkoTuNg2|tCW+u;#9si?TTMW zW^>hw$k9S3pD#@%7*8tI>0Bu>hn0|gE^E5gWAknWS`3V2)VJMjol3p=l~XC_j#DXn znNywp%$u{RKnx?Bh;npFMV6yw*XzLh=uFvliIr-3x;8K4wQ9UH6EC=hQu$c?$XqV( z#uYhJ%@t?k-T7KPd#vhKcnQA;?k#nXcovg7M7MYK(?@#QT9lQlZZwnu1Pj4dP2+x2Q3Cy2t zcPZ_4VNAQlX_Eyi(i@7jBjsGxRn}UulAA5M(<*{VGCg0auy{+gs#J0xbtPXy^{B5) z`01H^X11aR&Ss_#)#lULOvROSX=bM4B8wT+U$La@nDVr?V*EE99+_*R1mr7l8`l@BG$E|wvOZqBVFZ>D~~ z(pSs1;vtYT<>}m1H3|D{u9(RuDNS$gP4uP`eMy}6LMDTWsL5fC(zn;J0$7yvd}g}W zgFZFmIMvF_?!m$9;yu{FjsMgB4P1^>ka08FoLD@OA#87NYI11rs5IG* zC5g(h0+tq7Eqgd;dZ>>?mANIRGu4bFvXu(DZnid?&SbM?_pl^L@ie*OOvx|jb43?& z$#eCPWArBa{j`~Kra)dj&U`IfgbE`ybeVFdI7^i`6rxCCs#GYr*zyGClgLzY-(_nk zNS^uk*!Uibt4W$PzaQwoI?RQ#7W!qHLpayry{D~0pZ?_Wb%SqYlyPyXwm`wxjL4q^ zEm6~_+1U-Cdj6lRA-YP&@sQT<}uIX_?S7NE9c;}mmS@V?Jmgvcqe`HHp{w z`{R(gzQ%rLiTwwVxqdtFq5n^o*nbMyyc5%Yc8T5hBAQM&-ZK&@NsJAqq$?v`c#-g1 zdTHUSl8@a-9o`}Qx-Hagxm1Uz@z`L$8B@GpW#X30=@~rq^OD{@Hoj|MEImFlvVV9o zJvp#zY&cziOJDj^%e=6AZ_w&TSN)wVjpsIhd*Rs2T0AUS_iHzJXXCP~@wA4i#7jXF;stP>go(}GnGE0}&SV(0H>(K1a!OHRd%Q(fDbNpVP?a3;B;}(`Z{BuU+Gn8dDl?(6~?IL5+EhcW6AW@j;EJH9o2FhZ=vW@pl^ks*!8ReA_g} zH6}F{V(RfDNpV9amB6zQ8`|BDD+(*Py pb$Ge1L&z!WA*;HBJf>w;XOQQ#tm+E#C$+plgskcvUj|#X{@=>0;S&G= literal 0 HcmV?d00001 diff --git a/src/plugins/stardict/precompiled/i686/data.o b/src/plugins/stardict/precompiled/i686/data.o new file mode 100644 index 0000000000000000000000000000000000000000..f704a65619f8807792fdfe7afa6c9b8caa5bcd2d GIT binary patch literal 22876 zcmcJ1dwf*Y_3u72Cpl-rKmr7e3OW$L@Cr$Y3i2of5=40k35XTPNoJBvnLL;W1mqoJ z8ONxx(0cvZ`uJ7b+NxL|rHYC#BGp#gpDoqe7F%qg`0Mp`D{Za(zTds~NoGd0_x^DY zpPcVrd#%0J+H0@vaCEM@Ux}bRKji%`s9Yc?k5JE{1Js$+;#5^CO}*xrT(pt4 zyAHTxUZ8b|vs@j{JCS6ah`6!h*mD=)2^4&Ghqo=D@uGsPJjU`%*>Six&(i@;D z(Huiio$T%RG~K7JT}Muz?mCz_KUHU=V|Kq(cjsUn4&#YH4*m7^&MlCM znGq%#*ef#?%DSu1Ps zk%k+dL&^8h$X!*-IaXEs#SJThhO* z@m0YXP!&m5MLJIz@ev%h&&}+N)RpSmGYvYi&8n87@iU9YJ2%C}wxUetevG|1;YTu~ zX{svz?9sk82q}@A+wlzeqH|+hY`r+ElZ(BnD>{yA(V0E+=;)S@p4Sw`9-=W{ww zolYD)lqLd#Pkiv;$3HhNt35f8p6=Mr4&zF9rQrXcE4yIo z^IRd17hFL+T=C*BOu=ez=bTzsmIw!_wrcuo@e4D@2wf$E`^Fa~BFBr10#~0?2v(Mo z%o%}v*&)}MjG@q(x>Is8^7`4Mav?Y)N3I2D;KKPqoy-iATxEB>z@72S*ZAdDx#Qj2(1$ah z3v4ORbHO+zmEo?oilE^HbHgjTP?+F-vS0 zB3{f5K7I8Wou(}L-if=o-eJ#3+gi@W_+wg)_@b75ZaD{(+^&NgzpzCrx4UllnReBG zXDU_wXtKtel1H7+X(C<++l7olDi>ZCfbw#?1lq(@4Lieqn=&ezH71vc*cWw(&77lB zjj5E_sTz~IU`Vs5=HK+v5$)wM3*MM+Xs)rJAeDUW*`ucMUhnojAh;y;Zoi|i#602E zyZtVSLR5AB!`%8ZHnh(kzdGOb%C0#_Oq*Hs0orwbNpvjf4^~BLfec4#f$2DwvYb+{ zMMJ#{Yy~pUP7dzeW{UWLv<98qI%Ea50Ckw?+_qU(Z0@gECgP>t3yPcyjOqEQ1!c^t z^xP|lAxGqC8cn{(fSl^wFFPL}l-e$5i?&nK`Kh_}Ee`B4$O5H@eWxFtdYvzLoyqoj zC-B8~=N7NX-*d3*Fm`&+YjQAf4($39^dkE^I|@a7MQ2CR=|o|wqcDBD=-znxWG*+c zO-0=c`gTm5Jh+J#GNYIw&MEDXIXmyr{Mm*`esJOj=I+Hd#xjvDAO8aR)Z8&pTacRTqju?00ZMkNN{#v4GAG!{=aR3TA&Yjr8^HridLkvf zsVxQF=ImtGuTOt^x_g1qr=ja8Dln@!2C@alcw(xq2vfQ+wYU&Fb^)T{#rf2Ec+uT- zl4gr7JGVS77+?FM&efqG1w24a$8Fodu7mlz*5eFwB8gk)DOWtN^OQS2|HLMc=>e@z z3n)$!skxYN&M>7OV<*xEOPrX2=6EFO>{ur9yRJvu-Z{(Q6<`|f0Qt<95_n70L&V%`KfN!Vyuc%U2K7DDNIRy7{-EBH|>Dy zRoa##zxfp${kl`K8{G#`-`n*l?lL%C2X%=jv2Fc} zVJcxyKTyWyFdo*c|PnyFezpj-hetR=KF`eI4Z!`!Tr6FOIU(e)7J4&2@HnWkK?3der$e+lj;wMDgW6 zI(y0Wtn8OZhV8PY{x0gr*)fU4QBSA}LdH9Gxd?3|8mX5h6Y=Ra3$qrE0RCZBkvbQ+melr#Ynh#HtcK z5Q~eLTy&kRe%G~+`cXF}hy2+;m?<@U=+CaayAbsmGTZXIek9Axxy1C;W6bD@kEuDq zuDZKe<~qcvq`H`=&MIa+M(V_H1VGNg_8HPde4Ol#6Uwwb>oWmJ)wEBP22wJg+-mZ0 zqF{_NjrEBd(uWhO3)1b1l$@SuW2d_1_$)$e>0Dn*bg^T`p`@%m*_h!kHkI^s^fda@ zx9((5SFVBW=%1~lj0v6PCsw27?S`Dt3-nyRX%1dsrMeldLxwn6l&(E}ol41VVaE&H zN8~Qd)G`Je1-V0TA3JF10QaDC2MOUCBiw@q446GY2sethDw@Mld&z(q0~QVyA}3!A zkcHf#hB1`V=T-nCxlHgAw0S^XW>xR=8Y57F~CtMgcon}hO%zpD6poW$)I7V zxxmZ1{2VD>Fb>`hh9+A%K}|!n3Mdw0sA?iaq4p_9`7})G#MUufH`Z>PRSFYd@~TeJ z)L>(XF$Y?Ua{4;q0(mw_ZIk3Vl^NV~NiG~(=_PLjReo0CNXVpVIImxW5a*9H%B5u? zd^w_gDAkNg^DKv+`4ExO+AG=D;*l`qv>U^ALX6F9<@9D;e>>{FK>GqUBug?I^#@_R z?zNVipncZl#QrXP$ve|4#H92JDi$Y(Ad`SX$R$kJaFN$IWSwyvPP5B!=yuJ+t3lIp zbwSdwU5hbFF3a@*IH1cT@9lO%{1h!*9=7njGO-M{bcO zeV&)u_8d))@vNX5=W4RV^9g$A8KKEZo+b3^JfjM2T*YOct#rd@Tq?;*kB^#1>mE(> z+(%X8G&$4rA>Al34nW9NJjZh}xs!~klAQ0k4ukHQY|NEpjb{s0l^RQ=<^`U7^vqLX zTqDU#J@+#jGmM`};YFSW^lGlb(Qp;ldh+OVl_szBJWt{I+KsERf`P0tf>PDB!kmac zc;9E+9P_Uz=W(pf1lV@zWwMsM0SDOCeYx!US?Gw@^SD(_J3msf5Z2#F?N^~NtyOgC zfErsHng^g=j!Au9c7iqrz5!2IYofv%Pp_RS2JHeZea@$ONZo*ng4}0uKa37}2aX&Z z4vK;2>GZLhz!-SGqD<>fm>=k)4p*@)Otu&}Dh1NKoO0zyaL+M+i~FEYa8rg@%BO~W zzK+fR6g`HJ3;oKYS@RTb0~Zbfonsc^KBxpYgVRp=XnqaFfmckG0_=}@nB82<3UdY< z$CpZ89qxnLaO>}2exGq+t^sG@u1!*OJ4K($6qOdGpZ(5KM7jMuORqa5T&3n5^Dt_1 z%vW*GWBVNQO<8f26;v~1B0`pvV@zVXggv*6u`EB2KIGU2mzW{nrpzGY9W)wp3Ng(& zOJri8^U=0_QT)1M^QV&)LYc`xQ>;5Gv+qw+X$y}u*z1A>FUa2GttUU5oE6Kva zEwLtHep#&*Mb-~#;p%|2Fv5C*Io8x< zdPdGwJjwciS{jsvGV5mA3o5D-A@P8lOB1IlW-jyGPcv0Hsx^aFP2CZuOo;I?zY4tr z{>jYGeGaVGp|HTc&UzCS?x=2NB_ZjKsg9UdC!BT170h`i;7}`g*D1=Dv&+4iIe^vIx)?InOu~mnEqpYZfK%=ECJF z9$__;_n&feFZKzOZn*DV1BVKG5Z8^6Dly&Pk!kW>6-QyoH2IzyZk;CgD@v!y_t|55 zRm;fyfSTx46R8JOoc7q(K1SdnDs>m%W?O|M_bKuY+nUV!hZT93Z3Rg_!WGM1{B2u! z?}1L*945CALzr~c{pg4AJoh^|VeSQaqx*4d7yI`k<(;r@1KYh{dv0Av>c@`f>*(DR zit<`-FoI7is=)dKeLJA2LhBpkJ*B83>(?BIrxi8ADktw5Mft4b^!lKp#taTLM1=d< zDB{oM<2H`Nb1J5j)VRMu&vB}-PSdj&ACOcfY=b(asA*O^dA*97XCNhw2pU{|bL3u#1RpNf$Xrbp z3=f7Hh1(+!1g_#j&!3qLd2)-#QV2H|!A9PT@O}u5y9XGrp`3dq4rC3`e`VfSs|V)t z#%)5sIRAO9%ez1w5N+#0bR}>6e@LF!x*UGyO}YR2`wkxytQ_GCMNvhH+#)#zA zoGqg=&Duxa0!7WSzRz}-D(X_}2E;qBPOS*bEQ^vW6;&(F`X#zWa$HccVNvGSbXA!0@) z<&0J5=D?A6XfFr$aCu4ayepUF0+B~&Mx387#ILFTGU*VV8AdI2Mcn0#OJ!pA*hRZp zxlm46ICP5k7HWq^#^O<7Tux19&#s5IjSL6Ng|SGwu@XduLo6E^3#V~n;eO6Jvipn2 zN*%`^+I9|)uEr9jbk6cwY^*3i|s?*^^}>n}zWqg^iW6!yi$TyJz>dkzWzU|B*7PPot^V#rWU`5)^m!cqjaxiQtzFjFlJ2 z*>_W_oA_vM7!&z0V&ANY zNh@e)qMRUlT|5L?mpDRijDHRqh&$6ra6G0YV$mt#)`mzT7@88>7!&Cg8N`(Oa6Bd= z;rf<9K!{)<9w=>~ld*UpUW%MRU8pgJ60S`ULkVU#HMF%hs$x9c64IrO?IB9S`B*#{ zZd0{r;}o?{@L>#G^e7l^h%ZAC7mLC6NTMm+sw$AcFoo5j+_0ZM{E=(i(ABPzVfK_= zu8D?8IY_Rz%o4}WbZOqcsM*SG9hrr|!Z#hz(jZqMpzvU{euCJl9s z8Qyc`uDk46@?Vq9f3xh_cYbJ3IfAB5M~;BJb+x?@Ku&Yhk-O~X2T%^~Iba{373!Lu za9vbHX4%V`RL_wk8|+Tkg~RQ`;P%LW4u;M^-;%|7BH|a`8P8pJmU0k6+tn zm)Z|*K%;&3YWV)1uz#>xb1t(VY<|#HIdrxC$PxQVd*7X5I5+gpJ8y59^0FQ7TK%9s z>dvN*oA%j5?ZT#a?BA^Z@b$HJqO;3>`pBv-bb5C9u)X^7tJb?phq}rNU6Y2NaC_}1 zZnXq*zd;jW28?T?yzdhpo~WnANi+e2L!6xv-+cEb9D zM_l8Exk?M|+2nrYng%mN-H&g3!u?b6Qcsz^(MH~K=>5z+e`7cj4@G4z_@kjf(BF)k zQz0eV+Hu0@Z_p5Fi-pqYw)%J=oGu`>qzNcmh#G0h*AxwH@YN?88$(fFW3;WsH#X>N z55(fWNVp{&_q8>m0*k&7^8&4{ZK!~GA06?*)sS!W*w|=aV_VcmwNfs)DctT;Ui;RE zqOovWD|NDMEYaTH7LA9bV7#r(7inv4^3^PvySN(KLXn^^4Bc$sr#nyd$<153cyaZT z+RvAieG2*7+hXB3t(J_9B*yzj&2qfKX3-RH_D%GagB2VPZ^y=b;h1zSfDSYzA^`+} z-I_ev7j9~8i-ud9*eTgd_5l9HLmh}hRQuT$Z3)EF;}dI6#C^fG4Xu!Ej0B`3up4d- zUE&)XgJl2EF=QpavF($5aMZcQP>A{9oQ`)a6k6*;XWA3dkgrL`M%t8q#!B<*V(4)M zL#`Yv;aIeXqJWk_YeQ&!ma9G~5Ni)KgnY5Udh{UjInlb76~Rex5fw`t8)G3UjhYBDD_w$gngAVXo;IM5Os#+3{#+gxUg+xO^-fa zOG}{r^LWyo%xRV9>_#{Z1?zp2XUn#tnHgPDvc3)doiM&^yeKcND4ptrK_!{)1V;g* z7>l#7dL}otC0a2Wm=rqBN)|8e5KDgJ$`Hn8+iRM5Ocf&-V14}sICqfU<*FK(v*@et z>rI?n96ot`DeLeTcII4fe%0N_=fRk-SRDS+toC7yBp<^Zeoa<;9t|g_@w4so7`GZH z9;dxye+T@MTd4SN969*-+CTd+=3Hr8aJ25Pl#44*$Ng1mfxSPYPA{_O;dI$A$RYHL zH(`ha?QdxdhGgg%B;^G5dwn^d%aIJX216bG7?$90hwvv_6R{AUyf`yf!~-quf_p-! zwM`@z;=?#BDNX)BB+}3vh{i+<&K~~OHp2WWfrTj=sDVICtPe-yi9p03toKL4vA77w z5h%iN*bkD2ww>AQ6fC@o*T3hnhA@`3=!%XkO)NDn*;TsxKJk+xqIO&D)1)`kEIjv8tbj_``a2DQHymsu7eI!F|05$c+2F8 zN5~24$Ij)Cv^A{NWLqLGT0-&WwxC$Bq|P_bH?_2~w9;1+4MjqM7#6pZd5H3gwnVfc z6y4~XyL_>)qO9z~byFu-jK>+wUmsa3?eO3wjUgV5(NM_WfDnd)a)Q-EQD0$6pe4kH zt&wo++O)CN0}f6D`k2O0*^yX;jV!|e7ZV}ZF{e5djkZN)5NcHBHMF&~C*q-b%jcy< zSb9TFG!#P~=*bDY*hyLhMkN^010XH<{fTf8vCYoHwss~@w10H!1-Il4ZP8#%b{0N_ zTG?4YG6_*nw8pUEg@QgNmgBPQoL?J4EE`(mu+_gqAbpTZ94}PMyrIKFtSG7WyWL`KyZVzDUw*)%051W{*m}&^IzcJC;AU3T~?sKQ04gdOZ zEL@N2=x>GZ(lstS{R>cEgaXlqW@UxZjkSjwq}vO*_@EsZnzZQ2@_cQCYNNr>dNrtW zv8k82BL`V8KC-NrBE_Y;j593MAX`Nvb|5Z1Ty&T}GGJVbkQbcra@Ne_Hiev6w!FHw zcD28zZppmbg-e(C{c>THM+gDoDtT~aMj*~y&gF83eO+fWQ!zcU(NRnajJ8UC290Zu z+!T@6TAf_6E~-ST(m%Pb%K_y=##H5Uq82ZVpUhpk*t5fGHDlyxg&r}5{0(jGY8{n% z7r+7<72Ltw8(|evtyrs-*1j1;(=CDMT1bXlondZk53EaIg-X=x4AEnzmZ63~Lvu(> zX>M!5LvK7fWkWL-?O41mx^{{>g2qrCh_cNToNaL^4Me6$4U@}D%gahDq_Z4uj<#Hp z157Sw*7)(D%oBS?c+(DfP6ow7%(k>mNXSK3X0Tje{B4n-6HN9Ksi3BepOz7Kxy?<( zqj~=bFhi;~BJL2z!-`6i7#}~8 z=v!Js%o4rZ`GesYJFPYcybE9}X}D1Y6D=(pm2Zi7<212J&dk2KA{se_NLsmjFnhRO z0OdlUHu%2ffbs7m;_Hz{4Z1IVb3hMq|H7IPcYi}7ioA*>T3YoUEMz*fxr}L`VQr#a zht)}AE~U~NKhv^r+gsS$*d{j!#1$J)D7rpvb6mj_g5J|Bm>gjoM&NNPT~@n)Uq}38 zqQ{K)JeiGf2mL@O^j=J+URU(dM6N*o^eK+5z`rhm(-cG49>5twt}YlyzaO6i>!(VA z=d%`h#_8X^IN$wpCLv37k8~K-%0K~`2WnSak7YCx>Ptnv1y#y1MhZDzq(+Q+UM!e5 z?-E}L&LQLfpN=7-G`6t?W`Oai!e*z0b4)3pCq=2uveNok48>4=0%yGX`Y0x0DMeHb z9(3B$X&g~Ppxabag|ty#TIp0PvOK+2W0bpon%ee+T&`ib-&7zPXl)Ah`2wXv`dNzc zy=dA+rP$8>?G64opVLa~J47j-jYFjf&1B2~oZd>ESykE;ZA-K}r`~^y|AGY0)O}Ya zN_cb-XX9@s{&;}q-}(5%$h|5*G{ zAKuK#Yd&5HJ33h5lqaH0c}MQj&yg#G4D~q|pM2Mf9!R`|9()GP{Wq+Jm@5JRAl&Q~AaU}u} z1?^mptwvO^T%j4SK#pH@b1v#5KcUf)`(vpPryL>8qug#?c35vs!52#$0_cp#E|k;z zaSZ*q7IlmZzEj)RkN<_T<130{9|ow41${ZZy`a3aZWrwvtHST2N* z1${ZZ?}1L&w+Q;EhyD%0pA+W;D6e~K21ow+J(B1bUjw z5%7xhK;M=|j{&{kVWU42K);m6F9XdOscWFP2=q~hg#1jY zS{Z+S)a_ife|Z+YB8&EC(ZMV_oJF^0(Q(kuyIk7emBmkG(O(DcyxXPxce418fp*^Q zlK)~B|G%{iV#`#DS@45Vqc=C(jjc!W=UWatZms`R5CO=&bt;ospDfc(HIX!BH8Z-;GKFMsr0eghCs9xA0!Fs65p-iAsO10 z-u_n$if&1?QbK<$RSjSICG=}#zdwMNyU{q}5l*)+bJA(K5Ff-<_#H~E4=z0D@Y@%8 zvxKMwns_j{iuffVHUK@?Y>7UL`$Wh>wBP z&u1{|=jSnIwGg9#o)Or$N#lUBfb>Wqt{}qBYSu5n2O-2u@%<#?LhOSY4-qfJK0~~m zMwHw*;vylgCN9RlON71cL_DDU2NBOXPZ6Q-=NjM9_;-y3I7pIzfyUVymuqa-xLxDj z8Xwm9D~-oAexNZIn;P}<2Lqn-@c9-I{gpqFScY?%=JOX4l#6KGuJM~h_`jcsaXO;w z-`6-P2lZFr`~mdff%Y0A^f$784u0-Sgx;Hoh%3MN^DYow%8ZL*rhJ_X9nngm{z)JqK8i{=7+qKgWq^cUt4wmZGO>T&$7bd!rn`fllPF z%ZNWD!royb`fb1l<4^)*ew6~5U-DNF;0MXaA#5iR2i`k@p3y>lkBGmAS-(<MlJ$twKZ&dG8w3ydW3c}bQO7T|F)uG7BJbw2eyk8nG=HV$*8|;`z<<&>jNVWF zIK+ntJqK71J-tNu`v)SP^1`;tT`B^{vyAjC#-VCIj`^di<^NmbDI6;Ux^T!=rBhW)&JC6^##4sO>Z)<-35LLfe<2oSy z?<68F-NcJ9U&%*Yenf{+&lQ+sSPKw#VOaXv(1qVckOmeJ&%!up z9Hnub#>pDd1t|yDB_g#XF4TxACh2Q5hBUToyiViw8hbR}q47H!f2i>(jW20@RpXl) z-`4o9#*a1HhVp~IGi1N`3`88Ku~OqwjjJ>^YD{R{rIG)|2HW4G@nMYzHNL9xcN*pQ zJt6;zrUxL#Y|sCph{!WKkG)~sYUkS6mUgK9Zc4*}H$;scN@g9x) zG(N47Ki{U@n;K7OJf(4vNAV|UoTjlxW1YsJ#+b&P8u`AH`hTeL35_pl{FTOI8b8n| zuwSy>AdMq5PSD8zvViFcE86i^jOFzeVG>G=5*> zevL0`e2s`4{NI}X2NC){)tH0*pMDM1I7(woW2eSjG`^vc=LWX>P~)dW*s*Y4p#A|G z=Mo{eRO6R5#x!mvLVl;lq^|$E#$JuTAVUA|iID%J#=mR)m&QprZ_pmkDa0C$S8BYL zi1tB^Yju5>##@N6vrp3ph>$<1@ejKGQ;i;+TPQz<2zzBj$X9B-RM)T67}OZkxKrb! z8ei1-D~*5FcuJ!O=Nj5MN8>z=wHiYjV;Z*;vG;Uo`W7Pm<@t$v?$Y$Ln*N!_-)KBe z#JT(!&ll*IJTKw!G(ywUh@f%Qm3%xRNcw6`cW8RErf<{q9h%;+=>wX^wt@eeLZ91! I2(#4tKUd4RqyPW_ literal 0 HcmV?d00001 diff --git a/src/plugins/stardict/precompiled/i686/debug.o b/src/plugins/stardict/precompiled/i686/debug.o new file mode 100644 index 0000000000000000000000000000000000000000..9b108b7448ccc28399fcd4b22c5cac384d6e7d56 GIT binary patch literal 10284 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 literal 0 HcmV?d00001 diff --git a/src/plugins/stardict/precompiled/i686/memory.o b/src/plugins/stardict/precompiled/i686/memory.o new file mode 100644 index 0000000000000000000000000000000000000000..932c1c92f90fb282dbe4804e942d4a0cba2f8e32 GIT binary patch literal 14860 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 b`|5q?}bd zLR}6a3TYdz6exGO+M)bWj&?dsUaPt+VuB(`>m}&XWG8; z?(co)``-7yx9?fkp0lRMFbw54Lj~0YrPTU*PqIiuyJ}XAYM}CN|JcE%{pOqqxPLuz z^ytybOZ&9~c=N`2-RAz)bF@9srW{BUqDicFn-z18=i$wu{tK}n=gA?Y5D&@nKtB+K#j#Lw7*KK$WJ)R z*iu!RSDjLwUR`BYjB2l0Ik2?PbSEwCtKSx>^x@C`yIn!775fVbs-6>hLHp=ZC9|rk z^_2r#UQ)`KV$_El@IIxkF&eC!QKwX(Sq1CPh@KhkZB!~aM+GC%=(4C%Cc1TAH#AvA zwK&{p7>(poUny&nXBz5l>^fel2&$x!UXGisdK=?VIG%<|Mg1X^vc&}MXfo+k1X(x1 zi$*6!?I09QYS<)pr?vPFL8=!F) zB$uEQScsQ-XD76RnS4o^A#;EhmU$yIK>ZnDM9jHC=vwA8WLoAdP)69C4b4Evd=4%m zA@e~{5i1abigo4)MN^?>-L{O~8`#~w4PEgcG9M<<4qGD}UIwEBc=m*1);{pVw!x4B zZOS?i8sRC%eVR0_wQz)r@yLjEh{}yZ+Sa{PZW6NI`UEb+Q-y4@&ZTm*kS*5TbTv)L znbu-TTZC-2!nB<(xm8W!`u||`tt@V_47?)_W$C^f0F=Maxe6IBrr3;KF zGWh*03({f!z}VuZfl$3icHnH=%3C*w*W!+BCSTqWUl>~yTNKaa)7kQ%qvB<^_#cUQ zDpPWma!bkd)>s-tt6VY}-S%>sWZMQ(AHeZ4s2Q*Ffnm%JEd@+ zJZdQ8YZ2QtZvu~Z1i!JsSJp+Y53HILT0It2GetoD@)}w14Z$(y-IsF#_twbQ+!(yU z91D&6X6c+)Bd6~s&}>{>#^8^8A^Li5>Qa<}i(%Z-)*yp%@)CuiA=iPwAWr(N5DN$xL23J4(f5 zB3T?pbjhMhiCrW0+`4Om!|9@{P9@NT{qC$ z-Kw`~YkSejI>^V|*7j}$-(M&f(@t?`>&gq)wtD-$W5HZKkj}yQIJ&TOg`tqJQk*1` zoVcQlyp^~@NKYa$njD<(!2&K9`rAs$RMzoRp3USkNW5(LgkCg!2X>|qZ*H`-lPm0` zOWq=LCVuVupAC(0jfGRX`aIQRN+E$ytv?{wp{IAvIdFtx(1kUw>#d>7s-~J(ud-g{ zoXR7E2^IinqSsfdSlfB~VB8mDm078DAzwm0do`$wfcwI$%LP*Ul8AJBE zOJ>U$ilcf1E?&fvD(A77gUBW#y^dojEKHuvGML z#P6XfI$wKPrzrfcnzs_L4TWT7=Cxv=k(g) zn5Tl@e7$90)XpQ)tkkQ}cgY8@?(G5qyO3wNc+{`Sp^lYD>W@RzFU1cD{Z3T|Jn%xy`bVs zPqd((VJ*#>PPCw67AIOzHH@!0?{^KzBG=n*wD#|Jz|PQm4Z>jbw5W(BVjyjk#W!N&xj z73A*^^#5DIcLYBY3?P@3PZ4Ytj0^S&ZWbIAEDG)td{yub!9NPVFZh{Y6Sg?Vn<;pj zV3%Nz;08hdCPV#E!D|F>5!@^InBen*uL=H3FpN(L{WJ;A73>mRA-GO3Ex1$g8$`_E zCc*oK|9zpK6nsYbuL=FS;Gcy555Z4`|4%^^wa)k&1Q!x9-V(vJf_;K%BJ>MFyMjA} zf4$&d!AC^?xZu;me?{=u!hb{XZ-Va&9wjn=*qFqVh={LE@HFAC6kI3xHtQXFdcWfH q%3bg;R>lvD$hnedyX&TTWpsR@>Ujmi_&{`~U9TiLpJq z_hjaGfB)C_|K8udnU5`BwZgJ2WiCtkRhdCL&C#@JXi?{>acX_>wY7t%8;=H>Y)DU@ zJ$LS0@vsB_qsy8CG=-AjNS6kRCkBr+UccqAxR$oqyMCSz4lY*t5ra1cRH1P=zmmTg zXwnf%h#kH+b4EEe{n@ZfUt)TH+e+IyCyeL!+NObc}@#o}N(L@>a3%cJY?8 zrCUO!f?d2B4l7*i;^AFCFEnf62)C%ih-&M|9>Wu*EpL?yZdp)q^c4_&p_+Fj+cBx=`wsO?i7}Jf2=8Wm@?>d)XUaB@V zDIPAZbO%$Zp*XIzHc;#glsYC9JMB`(q+(~N)DbRr*0~Ncj!#WLikQfCi8F7Oa87}R z9H=7{&kP-NgQr`{4K9u#_h{R?HL zWsL6Rcd@Ww$fLBta0ZysPJf4Xub4Xc%9&Y5c5iN)IQZ)`CwFm0%5ywvXOr6Z1M?MU zTSc(amWmFyPhR~GN_7UQiCqy(GM{iVpkuJP{+^wE@)v(QckbO0^nx;pYt*05eg~1x zJ)!>a_@AG@?R&SOl?H!#X4diD%bKPZ52LD%GkRr-ZdO*BT|1M_DFe*lu0w_A&He89 zTV`=7_fLLQMJh+D*eSeBhg7JIaQF_=dx%wU)r}Z~@8;Tupucuvtx~=w<+p>u%Y#b! zaa-%$2FBrbQE+jvy+Ns}(JH8KMqHrCs~aq^j*00oR-1rjdyb4tLyPykH`}-gUQ&=c1+mB;| z@>To)ox*B=hQbm4X|VKF`5%X~UFEMrXuCQv8zxnYw=hTt%&P90&)Y_Hch$XHaVznw z0{={M3QpFDs=$LFBPa=+fRjJ+ByOwQ5%^_<`?Nn|UjV~E$ZCe%H$&Mop$gPn|D>CRYdW=8FTF8)P}8lG;OmtlTMc!U1Gn)tS%6GsePQj zE!GXXf=lc_QG2mGFF$o)2O(CIc?RRykvPgQ{38)AO!@=9ox;8Fzg6&zL< zY$LnDVU58IEq6FwGYwPY2eXch4{Dl z*uG_!{W=xPrEQfBrhF@e22?HWd@HSg(~)-KyY{1$^y$8-eUbU~Ti*waZb3eiP;8^` zBNBCMWz?jJYU_%mgxa>QNm^*g)>X*}ty8rO>Km}y5Wgz$LzG_KjoVM+V_O#l4?%0q zOfe}mbO@PPE$lAejDQNz$eNYbo{R8Z_azDr(kNm*1s`6E@v+v|A7!9chPKwKF)tHe zFh4nEsyTSe&K{1;A5?KBDXWL)iExotoD7Bchpa3&}$qr9tEyqfvWBkjI@Up*oi%*+^^TUcdELx490V&PFf9D&?Ftg%(gZ#mjMQ-*KNLy zZEkheXX%#ZfUwp!ZjJ9$R*rMSw`X92u1TIuou^|o-@_(H!jg}P5M@;AV(yLIz0 zhhKa0D0=hw#6z(5?Fo&GW&4y>Vq7Py-Q}!4>CNgMZ&vqKWVOf1iV=0eI;-=wuqwc; z>i&zW&$2JRY#l}?F|EINQu~sV8e3(r(?e6LVLY2AU)3J89>*l5haQm1EM$EjU`(rn z?hk7BF&%XO6WzaV(QS_7s;wV&tjFp0eNHLEW#cH@MPU9a!%g z@sxxSfv=!tG3teMTt8W_6E%8?u{tNWVQ^bD7L74rr{wZkWrZ}gHcUZrqjX|ecB%r8 zBGIY0GusK4#bC>Iz;GuE+Q(wUmL8&%$Fy!5B22aR(WgU&KSo0?*VaXr7SiZ;*YHBu z@M#)8OT_}mkVY@MhHYXvS@&(5F4O9qo=>5f7wXf53ZG(#KeH^nL1F@Qf7=bQTtcYu zbR0shjZ}0vhBTVUR$0&N*NCB0)*7d*4mD{#-E>!MvMib}bzL@AxNI~oGpyqr8F8l+ zns3oA;U^iYp1J`?NBJ{aH~A*^U&aa8IVGX2Z91H@l27R>^kPNRHAW9LSvH*pEsM^7 z&;e#xhfp1?SvptBs<~RMpENQE_#->!KFgwvXIzX9Jsv*o41f;Rd;%@#|0EA5=-T5j z_uu1?`n7D^CJs>9RxU@XKGn~V);qPM@U7q6u>!4yT(&il?oJkZ;>t@}yAt`FQW$lK zbYG+!zA6=qMHmFao2#`#4ncMu%fp`v5WQ3CSw|}-(I8m?@cNH#w&Axo^V}r?$ z*a!V1Blh&m?Q7n&=d}7q{or8AK5!swH*fOS-hObaeZX#bbDKSL)2_sea})M8bNlRR z3llinjf^Dhy|~+pyOZ{w1NPiQ_Vg3i9C-YizP`Tx!F_#&LSe@#d)l#mz6%@e1HR_Q z!T;>DTig1yZ{H^SvIVdGW|Q5z%5LzF{IceK_TB}!VZ^>o#}*#+O&{x<(QshUAH2QK z-n6%^@7Mx(`+R6GG(&VClSxK<;<(N1WEIs~-8Ny$!->>DHZu^n6<{grW;+xJ z+=V`yzyjssDdoyqdzbI3QB}(Z{jQF3EL9aczQp3i^G7p2#%~gZxSqggGd@PX>Q4V1 zfx#+e^gJNMJo*)bRd)n%t}%LU+=RNwN?ZK7*kzw>EA1>q*J$fVOB0gOH zG03NR>`k6rqSt%mCQlQO>#x_($hq8l>uuy*Q(HXojGPOnx4ljITr^W2`=R~HHF3Cj zTocE7{7gAq6TS66i~dJb<63~FGmoq>C!FcposGxxam53?D>GC0O|LM%1G6-zc+_?c zdlTs%#UryTN#x^M#v6kSh6ywV}@Thp`b5(tDkLG%> zraLpRQ}K}I+ES8MJbJmJzHDZ@;t|S~pc;u>zv6+&m9dZbvOj|+yR70(1@IzR62hNKm@a59}0H)io-LMfqzbYfc}uDI7yYr5wd3ENhQC`GVJk9kyhqBo`{c!|#R_}5S<(^2zQ_;10 zODSt5Lp`=Ql%VO!6!I#E-9>d3y0^yjxo9C5?@`$}WY__6sykCaO>`wa-I>f_chFxI z$>=$LXQfUdApUx}h5DzsuOk=DgIX}j)v z^g)Y$N@Z}EaTOI4ikWGZj5-#Siez-jD9dt*}a@<2i_9*`7pqzBQ9gKoU!~lJ(4<8<{&NGOrbDEG4GIE*FyzMZn%gWX3!%M^SBW;nka7#9xjH8ogg9c^JmYSrTauTvD2SUBVZUrw-wM)=-KE%tY@wR^HlVPJbTu3 zyNqJ?x|@PdoH=VpP4?`|97-3EemX`^Z%En16 zU2A9B&MQYV>u0pP!1R)Z6xxWBS(~_8)?r~A`?-+j0)j5)6vy(W#{)`<$FOOyT)K2o zxCNtY*8gd6sYq^T3L^%X&pOy|?l3wddFB&Av&U4VE0@DX#`Vu#N4di7>wDZ05~2MS$jh){4@7R$!ceH1w*BdCg`Gx>M~ zwV#cN-Mv*sx-+R17Im}B{9~L76C6(zHh+D!;oG}6nH`JgJnWqA)pW5^JFuyZhlKvL z!%nTw-Q+kr>T4qcn-~V5|$Nxo{%k;;`A@J6t zZ2_K_5PA-eI4-@i9V-Xym`;MDSdu+!rA;_f*sF zl40zagBiAXJ9%%j0d^s}9mtS#Yl`p>@8D8$4aV+0Fu{kz=^ZtVgB`=0YpB12yX*7??LF_K1AOMZr+1XPh0c;gZ$&*=Di2` z=fTbU4)TY=&3g{=r@+m{d=7(~_Z`$fKScjCaP!`S`ri%F{}J50_n_YP%qhm7JcM5a zek+FEBhb-)$q@a@A$$$EdH+HC>%h%>5Atqs^S*;THN?LFZr*oL|50%Bo`d`@aPxkH zoc}B{?={H32yWhIkUs=&F4pf~!Oi;&>iMrE^B#lz7`SIl!3e5pmF;OvE|w zN+RmfF8BqY^**KUC!ep>g$2jpGQPF z^C-uMzg_U*&~t_GwSw1EKE-)cO1qoM!ziD4sZ!qqQhrS2zZ3oka&+P-99yU#3-ry# zbAWKZJoU9IwMO^`^0{a~a^(CO!LJZe-$$swN~v!U->=kniHnr_5%q}wGr?a`j)Tle z;eQddMnI1C8w;fUWO5uZ0Qf}(_F-bRb8fKEM?8%XF$9%0#`&KC5nZi0s-h8Hr;+Cj z>XD+xcEJw84TAdF19oxYJfqNWyWs7Dy9GZl_;tYpf`?rWYO%XkaFfWhg7*r3 zLG*hC9~AjF1&;~-MDPv437nTGhwnR>&rHFH$QKJn1(Skz3Vu`YyF~auEqF}iuL+(J z`CEeTh}_29XZcNn7ZDMsRdAumV}ePM4+w4-`IiO1Ci2Gwza{eHf+q!E7yX-pe--%{ z^bzxk2)>_)d@d7QCi3e9Q-XZgLc5y<2SxsX@P`GT5&4gV|3vU5k)INrh=*U@FGR$h zDL7x`R|sD!xLM@=!jpo#M7~G(eS!~*{0D+Bi2Q`$8zTQ7;oQTRMTjYI$_@}q_|CsPW!B2?%ej?`Ve&L5ie?;)O$WI9Wh2Tk%pAr6+;5#C(!CuC^ z#|t(I&LLt>7PxMsetO@*p$JDC&GkM5j;&jBy{~|;6W&h**ZT?l?-G8u=pPoY_YvrS zApE%KUlIPQ@VAAZ6<)`69Pt~8@NW^W_Y?3X!k3ADqj3J*m-ah^-z=QxEXMny@cqIM z3V%-c3&KwdKP{XuZs;E%;u99$B>WQLmkRF?zD{_*@TBltg@0W5KH(1t-!EM6Ke&HR T_zR-PGJ;=p%XtD=C++sXv)p$G literal 0 HcmV?d00001 diff --git a/src/plugins/stardict/precompiled/i686/xmalloc.o b/src/plugins/stardict/precompiled/i686/xmalloc.o new file mode 100644 index 0000000000000000000000000000000000000000..502c354b81e0fdbcc362eecc7551349084102263 GIT binary patch literal 6200 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 literal 0 HcmV?d00001 diff --git a/src/plugins/stardict/src/engine_stardict.c b/src/plugins/stardict/src/engine_stardict.c new file mode 100755 index 0000000..f96fe76 --- /dev/null +++ b/src/plugins/stardict/src/engine_stardict.c @@ -0,0 +1,1730 @@ +/****************************************************************************** +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +******************************************************************************/ + +// header with data structure and function definition for XDXF engine. +// Also Engine API. +#include +//------------------------------------------------------------------------------ + + + + +/** \brief Read and return part of compressed file (dictzip) + * + * @param part FilePart* defines file part which we want to read + * @param data SDData* structure from which we get filename of file to + * read (data->dic_file_name) + * @return gchar* buffer with content of file part, or NULL if there + * were some problems + */ +static gchar* sd_read_file_part_dz(FilePart* part, gchar* file) +{ + eg_debug("-> %s() called.\n",__FUNCTION__); + timer(TIMER_START,(gchar*)__FUNCTION__); + gchar* result = NULL; + + // read into the buffer 'result' + dictData* header = NULL; + header = dict_data_open(file , 0 ); + result = dict_data_read_(header,part->offset,part->length,NULL,NULL); + dict_data_close(header); + + timer(TIMER_STOP,(gchar*)__FUNCTION__); + eg_debug("<- %s() returned string=\n%s.\n",__FUNCTION__,result); + return result; +} +//------------------------------------------------------------------------------ +/** \brief Read and return part of uncompressed file. + * + * @param part FilePart* defines file part which we want to read + * @param data SDData* structure from which we get filename of file to + * read (data->dic_file_name) + * @return gchar* buffer with content of file part, or NULL if there + * were some problems + */ +static gchar* sd_read_file_part(FilePart* part, gchar* file) +{ + eg_debug("-> %s() called.\n",__FUNCTION__); + timer(TIMER_START,(gchar*)__FUNCTION__); + guint length = part->length; + + // open file + gint fd = open(file, O_RDONLY); + if(fd == -1) + { + eg_debug("---> Error: could not open *.dict file!\n"); + timer(TIMER_STOP,(gchar*)__FUNCTION__); + eg_debug("<- %s() finished with error.\n", + __FUNCTION__); + return NULL; + } + + // read from file to buffer + gchar* result = (gchar*)g_try_malloc0(length+1); + gint readed = (gint)read(fd, result, length); + if(readed != part->length) + { + eg_debug("---> Error: could not read *.dict file!\n"); + g_free(result); + result = NULL; + } + result[length] = '\0'; + + timer(TIMER_STOP,(gchar*)__FUNCTION__); + eg_debug("<- %s() returned string=\n%s.\n",__FUNCTION__,result); + return result; +} +//------------------------------------------------------------------------------ +/** \brief Search offset and length of article in dictionary for word. + * + * @param data SDData* where to search for descriptor of article + * @param word gchar* for what word we are looking format + * @return FilePart* describing part of file containing article about + * word or NULL if there were some problems + */ +FilePart* sd_find_file_part(SDData* data, gchar* word) +{ + eg_debug("-> %s() called.\n",__FUNCTION__); + timer(TIMER_START,(gchar*)__FUNCTION__); + + FilePart* result = NULL; + data->sd_seek_idx(data->idx_file, 0, _FILES_WRAPPER_BEG); + gchar buffer[WORD_LIST_BUFFER_LENGTH + 1]; + gint readed =0; + gint offset = 0; + gchar* tmp = NULL; + guint len = 0; + guint pl = strlen(word); + gboolean further = FALSE; + do + { + readed = data->sd_read_idx(data->idx_file, + buffer + offset, + WORD_LIST_BUFFER_LENGTH - offset + ); + if(readed < 0) + { + eg_debug("---> Error while reading file for searching" + " matched FilePart in dictionary to word: %s", + word + ); + break; + } + else + { + further = (readed == (WORD_LIST_BUFFER_LENGTH-offset)); + } + tmp = buffer; + + guint i = 0; + gint min = _MIN(readed, WORD_LIST_BUFFER_LENGTH-270); + while(ioffset = ntohl(val); + tmp = tmp + sizeof(guint); + memcpy(&val,tmp,sizeof(guint)); + result->length = ntohl(val); + further = FALSE; + break; + } + // calculate length of word + len = strlen(tmp)+1; + // jump in buffer over this word, and ... + tmp += len; + // ...skip offset and length of translation + tmp += 2 * sizeof(guint); + // update i value + i = i + len + 2 * sizeof(guint); + } + if(!further) break; + offset = WORD_LIST_BUFFER_LENGTH - i; + g_memmove(buffer,buffer+WORD_LIST_BUFFER_LENGTH-offset, offset); + } + while(further); + + timer(TIMER_STOP,(gchar*)__FUNCTION__); + if(result) + { + eg_debug("<- %s() return: OFFSET=%d LENGTH=%d.\n", + __FUNCTION__, + result->offset, + result->length + ); + } + else + { + eg_debug("<- %s() didn't find proper FilePart!\n",__FUNCTION__); + } + return result; +} +//------------------------------------------------------------------------------ +/** \brief Close and clean unused dictionary. + * + * This function is called whenever you call macro dict_eng_destroy(). Every + * engine could have some memory allocated for its, so it is obligatory to call + * this function every time when You do not need engine no more. + * + * @param engine Engine* to close and clean + */ +void sd_engine_close(Engine* engine) +{ + eg_debug("StarDict/%s->%s() called.\n-->PARAM: engine adress=%p\n", + __FILE__, + __FUNCTION__, + engine + ); + + g_assert(engine != NULL); + SDData* data = (SDData*)(engine->engine_data); + + data->sd_close_idx(data->idx_file); + g_free(data->idx_file); + g_free(data->dict_path); + g_free(data->idx_file_name); + g_free(data->ifo_file_name); + g_free(data->dic_file_name); + g_free(data->icon); + g_free(data->lang_from); + g_free(data->lang_to); + g_free(data->title); + g_free(data); + g_free(engine); + eg_debug("StarDict/%s->%s() engine at adress=%p is deleted.\n", + __FILE__, + __FUNCTION__, + engine + ); + engine = NULL; +} +//------------------------------------------------------------------------------ +/** \brief Create engine to dictionary in given directory. + * + * Construct and initialize new engine from concrete location. + * + * @param location gchar* from where we are trying to load StarDict + * dictionary + * @param auto_cache gboolean flag defining if we want automaticlly turn + * on the optimization of newly created engine. In StarDict dictionaries this + * flag is unused. + * @param progress_handler gpointer is a function which will be called + * from time to time + * while optimization proccess is running. As far as there is no optimization + * for StarDict dictionaries, this flag is unused either. + * @param progress_data gpointer given as a parameter to progress_handler + * @param seed gdouble tells how often to call progress_handler + */ +Engine* sd_engine_create(gchar* location, + EngineOptimizationFlag auto_cache, + cb_progress progress_handler, + gpointer progress_data, + gdouble seed + ) +{ + eg_debug("StarDict/%s->%s() called.\n" + "-->PARAM:location=\'%s\'\n" + "-->PARAM:auto_cache=%d\n", + __FILE__, + __FUNCTION__, + location, + (guint)auto_cache + ); + g_assert(location != NULL); + + sd_timer(TIMER_START,(gchar*)__FUNCTION__); + + gchar* tmp = g_strdup(location); + string_to_path(&tmp); + + Engine* result = (Engine*)g_try_malloc0(sizeof(Engine)); + result->engine_location = sd_engine_location; + result->engine_is_optimized = sd_engine_is_optimized; + result->engine_optimize = sd_engine_optimize; + result->engine_search_word_list = sd_engine_search_word_list; + result->engine_search_word_translation = + sd_engine_search_word_translation; + result->engine_close = sd_engine_close; + result->engine_status = sd_engine_status; + result->engine_error_message = sd_engine_status_message; + result->engine_set_callback = sd_engine_set_callback; + result->engine_set_progress_seed = sd_engine_set_progress_seed; + result->engine_set_auto_free = sd_engine_set_auto_free; + result->engine_get_lang_to = sd_engine_get_lang_to; + result->engine_get_lang_from = sd_engine_get_lang_from; + result->engine_get_title = sd_engine_get_title; + result->engine_get_icon_path = sd_engine_get_icon_path; + result->engine_add_word = sd_engine_add_word; + result->engine_remove_word = sd_engine_remove_word; + + SDData* data = (SDData*)g_try_malloc0(sizeof(SDData)); + result->engine_data = (gpointer)data; + data->dict_path = g_strdup(tmp); + data->cb_progress_caching = progress_handler; + data->cb_progress_caching_data = progress_data; + data->cb_progress_caching_seed = seed; + data->cb_progress_word_list = NULL; + data->cb_progress_word_list_data = NULL; + data->cb_progress_word_list_seed = 0.01; + data->cb_progress_word_trans = NULL; + data->cb_progress_word_trans_data = NULL; + data->cb_progress_word_trans_seed = 0.01; + data->cb_search_word_list = NULL; + data->cb_search_word_list_data = NULL; + data->cb_search_word_trans = NULL; + data->cb_search_word_trans_data = NULL; + data->auto_free = FALSE; + + if(!sd_read_files_names(data)) + { + eg_warning("Error while loading dictionaries filenames!\n"); + result->engine_close(result); + result = NULL; + sd_timer(TIMER_STOP,(gchar*)__FUNCTION__); + return result; + } + if(!sd_parse_ifo_file(data)) + { + eg_warning("Error while reading *.ifo file!\n"); + result->engine_close(result); + result = NULL; + sd_timer(TIMER_STOP,(gchar*)__FUNCTION__); + return result; + } + // there are no information about this parameter of dictionaries in + // StarDict format + data->lang_from = NULL; + data->lang_to = NULL; + // StarDict dictionaries do NOT support different icons, so set global + data->icon = g_strdup(ICON_PATH); + + sd_timer(TIMER_STOP,(gchar*)__FUNCTION__); + eg_debug("StarDict/%s->%s() returned Engine at adress=%p\n", + __FILE__, + __FUNCTION__, + result + ); + g_free(tmp); tmp = NULL; + return result; +} +//------------------------------------------------------------------------------ +/** \brief Search for word list in dictionary. + * + * @param engine Engine* to search in + * @param pattern gchar* to search for + */ +void sd_engine_search_word_list(Engine* engine, + gchar* pattern, + gpointer cb_data) +{ + eg_debug("-> %s() called. Searching words list\n" + "--->PARAM:engine at adress=%p\n" + "--->PARAM:pattern=\"%s\"\n", + __FUNCTION__, + engine, + pattern + ); + g_assert(engine != NULL); + g_assert(pattern != NULL); + + sd_timer(TIMER_START,(gchar*)__FUNCTION__); + SDData* data = (SDData*)(engine->engine_data); + if(data->cb_search_word_list == NULL) { + eg_warning("---> %s() callback for Word List not set. " + "Searching aborted.\n", + __FUNCTION__ + ); + sd_timer(TIMER_STOP,(gchar*)__FUNCTION__); + return; + }; + + data->sd_seek_idx(data->idx_file, 0, _FILES_WRAPPER_BEG); + gchar buffer[WORD_LIST_BUFFER_LENGTH + 1]; + gint readed =0; + gint offset = 0; + gchar* tmp = NULL; + guint len = 0; +// guint pl = strlen(pattern); + GPatternSpec* regex; + regex = g_pattern_spec_new (pattern); + + gboolean further = FALSE; + guint count = 0; + GArray* result = g_array_new(TRUE, TRUE, sizeof(gchar*)); + do + { + readed = data->sd_read_idx(data->idx_file, + buffer + offset, + WORD_LIST_BUFFER_LENGTH - offset + ); + if(readed < 0) + { + eg_debug("---> Error while reading file for searching" + " matched words in dictionary to pattern: %s", + pattern + ); + break; + } + else + { + further = (readed == (WORD_LIST_BUFFER_LENGTH-offset)); + } + tmp = buffer; + + guint i = 0; + gint min = _MIN(readed, WORD_LIST_BUFFER_LENGTH-270); + while(icb_search_word_list_data; + } + data->cb_search_word_list(result, + pattern, + cb_data, + ENGINE_NO_ERROR + ); + sd_timer(TIMER_STOP,"callback for returning word LIST END"); + guint i = 0; + for (i=0; ilen; i++) + { + g_free(g_array_index(result, gchar*, i)); + } + g_array_free(result, TRUE); + g_pattern_spec_free (regex); +} +//------------------------------------------------------------------------------ +/** \brief Search translation of word in dictionary. + * + * @param engine Engine* to search in + * @param word gchar* to search for + */ +void sd_engine_search_word_translation(Engine* engine, + gchar* word, + gpointer cb_data) +{ + eg_debug("-> %s() called.\n" + "-->PARAM:engine at adress=%p\n" + "-->PARAM:word=\'%s\'\n", + __FUNCTION__, + engine, + word); + g_assert(engine != NULL); + g_assert(word != NULL); + // start sd_timer for this function + sd_timer(TIMER_START, (gchar*)__FUNCTION__); + SDData* data = (SDData*)(engine->engine_data); + gchar* trans0 = NULL; + + if (NULL == cb_data ) + { + cb_data = data->cb_search_word_list_data; + } + + FilePart* part = sd_find_file_part(data, word); + if(!part) + { + sd_timer(TIMER_STOP,(gchar*)__FUNCTION__); + eg_debug("<- %s did not found any article for word: %s", + __FUNCTION__, + word + ); + + data->cb_search_word_trans(NULL, + word, + cb_data, + ENGINE_NO_ERROR + ); + return; + } + + trans0 = data->sd_read_dic_part(part,data->dic_file_name); + + if(!trans0) + { + sd_timer(TIMER_STOP,(gchar*)__FUNCTION__); + eg_debug("<- %s could not read from *.dict[.dz] file: %s", + __FUNCTION__, + data->dic_file_name + ); + + data->cb_search_word_trans(NULL, + word, + cb_data, + ENGINE_NO_ERROR + ); + return; + } + + // "parse" returned part of file with article about word + gchar* trans = sd_parse_stardict_article(trans0, + data->types, + part->length + ); + g_free(trans0); trans0 = NULL; + + // check if returned article has apprioprate format (only text) + if(!trans) + { + sd_timer(TIMER_STOP,(gchar*)__FUNCTION__); + eg_debug("<- %s could not parse stardict article!", + __FUNCTION__ + ); + + data->cb_search_word_trans(NULL, + word, + cb_data, + ENGINE_NO_ERROR + ); + return; + } + + sd_timer(TIMER_STOP,(gchar*)__FUNCTION__); + sd_timer(TIMER_START,"callback for returning word's translation START"); + // calling callback for word translation + + data->cb_search_word_trans(trans, + word, + cb_data, + ENGINE_NO_ERROR + ); + + + sd_timer(TIMER_STOP,"callback for returning word's translation END"); + + /*if(data->auto_free) { + eg_debug("---> %s() deleting all dynamic data because " + "AUTO_FREE=TRUE\n", + __FUNCTION__ + ); + g_free(trans); + }*/ + g_free(trans); + trans = NULL; +} +//------------------------------------------------------------------------------ +/** \brief Print only beggining end end of given buffer + * + * @param buffer to present + */ +static void sd_print_buffer_partial(gchar* buffer) +{ +#ifndef NOLOGS +#define PRINT_LEN 100 +#define EDGE "\n-------------------------------------------------------------\n" + gchar tmp = 0; + guint len = strlen(buffer); + if(!buffer) + { + eg_debug("Buffer is empty!\n"); + } + else if(PRINT_LEN >= len) + { + eg_debug("Buffer(%p):whole=%s%s%s", buffer, EDGE, buffer, EDGE); + } + else + { + // printf first 100 bytes + tmp = buffer[PRINT_LEN+1]; + buffer[PRINT_LEN+1] = '\0'; + eg_debug("Buffer(%p): first %db=%s%s (....)\n\n", + buffer, + PRINT_LEN, + EDGE, + buffer + ); + buffer[PRINT_LEN+1] = tmp; + + //print last 100 bytes + eg_debug("Buffer(%p): last %db=\n(....)%s%s", + buffer, + PRINT_LEN, + buffer+len-PRINT_LEN, + EDGE + ); + } +#endif +} + +/** \brief Check and parse pure stardict data containing whole article. + * + * @param buf gchar* buffer with pure data get from stardict + * *.dict[.gz] file + * @param type gchar* sametypesequence defined in *.ifo filed - + * defines what kind of data will be in *.dict[.dz] or NULL if *.ifo did not + * define this + * @param length guint length of buffer buf + * @return gchar* new allocated buffer with proper translation or NULL + * if there were no good data for engine (e.g. if engine do not handle PNG, WAV + * file etc.) + */ +gchar* sd_parse_stardict_article(gchar* buf, gchar* type, guint length) +{ + eg_debug("-> %s()\n--->PARAM:type=%p\n--->PARAM:length=%d", + __FUNCTION__, + type, + length + ); + sd_print_buffer_partial(buf); + sd_timer(TIMER_START, (gchar*)__FUNCTION__); + g_assert(buf != NULL); + g_assert(length > 0); + + gchar* result = (gchar*)g_try_malloc0(sizeof(gchar)); + result[0] = '\0'; + gchar next_type = 0; + gchar* ptr = buf; + + while(length > 0) + { + if(type == NULL) + { + memcpy(&next_type, ptr, sizeof(gchar)); + ++ptr; + --length; + } + else + { + next_type = type[0]; + ++type; + } + + // check if this is a text or binary data + // all text data are signaled by low level letter + if(g_ascii_islower(next_type)) + { + // text, so add this to translation + gchar* new_txt = sd_get_buffer_from_article(&ptr, + &length + ); + gchar* new_tra = g_strconcat(result, + new_txt, + "\n
", + NULL + ); + g_free(result); + result = new_tra; + new_tra = NULL; + g_free(new_txt); + new_txt = NULL; + } + else + { + // binary, so skip it + // read hom many bytes to skip + guint len = 0; + g_memmove(&len, ptr, sizeof(guint)); + //omit in buf and len - field containting size of data + length -= sizeof(guint); + ptr += sizeof(guint); + // conver network byte oredered guint to host ordered + len = ntohl(len); + // skip uneeded bytes + length -= len; + ptr += len; + } + } + + sd_timer(TIMER_STOP, (gchar*)__FUNCTION__); + eg_debug("<- %s() returned buffer at %p\n",__FUNCTION__,result); + return result; +} +//------------------------------------------------------------------------------ +/** \brief Get string from buffer. + * + * Function gets from buffer string of char NULL-terminated, but no more than + * len. Additionaly it update start position of the buffer and lenght of buffer + * left. + * + * @param buffer gchar** with part of article + * @param len guint number of bytes which could be maximally readed + * @return gchar* next string available in the buffer + */ +gchar* sd_get_buffer_from_article(gchar** buffer, guint* len) +{ + eg_debug("-> %s\n",__FUNCTION__); + g_assert(len > 0); + + guint buf_len = 0; + gchar* tmp = *buffer; + while(tmp && *len > 0) + { + ++buf_len; + ++tmp; + --(*len); + } + + gchar* result = (gchar*)g_try_malloc0(buf_len+1); + g_memmove(result, *buffer, buf_len); + result[buf_len] = '\0'; + + *buffer = tmp; + eg_debug("<- %s\n",__FUNCTION__); + return result; +} + +//------------------------------------------------------------------------------ +//============================================================================== +//============================================================================== +//============================================================================== +//----------------------------------------------------------- FINISHED FUNCTIONS +//============================================================================== +/** \brief Trying to find file names of default StarDict dictionary files + * + * @param data SDData* this is a structure from which function gets + * directory to search in (data->dict_path) for files. Also puts there founded + * (if any) filenames (data->[idx|ifo|dic]_file_name) + * @return gboolean telling us are there all of obligatory StarDict files + * in directory: data->dict_path + */ +gboolean sd_read_files_names(SDData* data) { + eg_debug("-> %s()\n",__FUNCTION__); + GError *dir_err = NULL; + gchar* tmp = data->dict_path; + GDir* dir = g_dir_open (tmp, 0, &dir_err); + if(!dir) + { + eg_debug("---> Could not open a dir:\n%s\n",data->dict_path); + return FALSE; + } + gboolean ifo = FALSE; + gboolean idx = FALSE; + gboolean dic = FALSE; + const gchar* fn = g_dir_read_name(dir); + + while((fn != NULL) && !(ifo && idx && dic)) + { + if(g_str_has_suffix(fn, ".ifo")) + { + data->ifo_file_name = g_strconcat(tmp,"/",fn,NULL); + ifo = TRUE; + }; + if(g_str_has_suffix(fn, ".idx")) + { + data->idx_file_name = g_strconcat(tmp,"/",fn,NULL); + data->idx_compressed = FALSE; + data->sd_open_idx = sd_open; + data->sd_read_idx = sd_read; + data->sd_seek_idx = sd_seek; + data->sd_close_idx = sd_close; + idx = TRUE; + }; + if(g_str_has_suffix(fn, ".idx.gz")) + { + data->idx_file_name = g_strconcat(tmp,"/",fn,NULL); + data->idx_compressed = TRUE; + data->sd_open_idx = sd_open_z; + data->sd_read_idx = sd_read_z; + data->sd_seek_idx = sd_seek_z; + data->sd_close_idx = sd_close_z; + idx = TRUE; + }; + if(g_str_has_suffix(fn, ".dict")) + { + data->dic_file_name = g_strconcat(tmp,"/",fn,NULL); + data->dic_compressed = FALSE; + data->sd_read_dic_part = sd_read_file_part; + dic = TRUE; + }; + if(g_str_has_suffix(fn, ".dict.dz")) + { + data->dic_file_name = g_strconcat(tmp,"/",fn,NULL); + data->dic_compressed = TRUE; + data->sd_read_dic_part = sd_read_file_part_dz; + dic = TRUE; + }; + fn = g_dir_read_name(dir); + } + g_dir_close(dir); + + if(ifo && idx && dic) + { + eg_debug("---> Dictionary files :\nifo=%s\nidx=%s\ndict=%s\n", + data->idx_file_name, + data->idx_file_name, + data->dic_file_name + ); + data->idx_file = data->sd_open_idx(data->idx_file_name); + if(data->idx_file == NULL) + { + g_free(data->idx_file_name); + data->idx_file_name = NULL; + g_free(data->ifo_file_name); + data->ifo_file_name = NULL; + g_free(data->dic_file_name); + data->dic_file_name = NULL; + eg_debug("---> Could no open *.idx file!"); + return FALSE; + } + eg_debug("<- %s()\n",__FUNCTION__); + return TRUE; + } + else + { + if(idx) + { + g_free(data->idx_file_name); + data->idx_file_name = NULL; + } + if(ifo) + { + g_free(data->ifo_file_name); + data->ifo_file_name = NULL; + } + if(dic) + { + g_free(data->dic_file_name); + data->dic_file_name = NULL; + } + } + eg_debug("<- %s()\n",__FUNCTION__); + return FALSE; +} +// ----------------------------------------------------------------------------- +/** \brief Check if location is a proper location of StarDict dictionary. + * + * @param location gchar* location to check + * @return gboolean telling if this location is location of some + * StarDict dictionary + */ +gboolean sd_engine_check(gchar* location) +{ + eg_debug("-> %s()\n--->PARAM:location=%s\n", + __FUNCTION__, + location + ); + g_assert(location); + + gboolean result = TRUE; + gchar* filepath = g_strdup(location); + string_to_path(&filepath); + if (filepath == NULL) + { + result = FALSE; + eg_debug("---> %s is not a proper path!\n",location); + } + else + { + SDData* tmp = g_try_malloc0(sizeof(SDData)); + tmp->dict_path = filepath; + + result = sd_read_files_names(tmp); + + g_free(tmp->idx_file_name); + g_free(tmp->ifo_file_name); + g_free(tmp->dic_file_name); + g_free(tmp); tmp = NULL; + }; + g_free(filepath); + + eg_debug("<- %s() returned bool statement=%s.\n", + __FUNCTION__, + PRINT_STATE(result) + ); + return result; +} +//------------------------------------------------------------------------------ +/** \brief Simple measuring of time needed for functions to work. + * + * @param start gboolean if we pass flag TIMER_START timer will start + * to work and if we pass TIMER_STOP timer will stop working and print short + * summary of working time + * @return gdouble time in seconds for which function has been working + * or (if we pass TIMER_START as a flag) 0.0. + */ +static double timer(gboolean start, gchar* message) +{ + static GArray* stack = NULL; + static gboolean first_run = TRUE; + static struct timeval actual_time; + static struct timeval last_time; + static struct timeval result; + static double seconds = 0.0; + if(first_run) + { + first_run = FALSE; + stack = g_array_new(TRUE, TRUE, sizeof(struct timeval)); + }; + + if (start) + { + eg_debug("TIMER:function %s()'s timer has started.\n",message); + g_array_prepend_val(stack, actual_time); + gettimeofday(&g_array_index(stack, struct timeval, 0),NULL); + return -1.0; + } + // we just want to end some sd_timer - print some information about + // working time; + else { + gettimeofday(&actual_time,NULL); + last_time = g_array_index(stack, struct timeval, 0); + g_array_remove_index(stack, 0); + + if (actual_time.tv_usec < last_time.tv_usec) + { + int nsec = (last_time.tv_usec - actual_time.tv_usec) / + (1000000 + 1); + last_time.tv_usec -= 1000000 * nsec; + last_time.tv_sec += nsec; + } + if (actual_time.tv_usec - last_time.tv_usec > 1000000) + { + int nsec = (last_time.tv_usec - actual_time.tv_usec) / + 1000000; + last_time.tv_usec += 1000000 * nsec; + last_time.tv_sec -= nsec; + } + result.tv_sec = actual_time.tv_sec - last_time.tv_sec; + result.tv_usec = actual_time.tv_usec - last_time.tv_usec; + seconds = (((double)(result.tv_usec)) / 1e6) + + ((double)(result.tv_sec)); + + eg_debug("TIMER:Function \'%s()\' was working for: %g " + "[s] or %ld [us].\n", + message, + seconds, + ((long)(result.tv_sec*1e6)+(result.tv_usec)) + ); + // stack is empty so we delete everything + if(stack->len == 0) + { + g_array_free(stack, TRUE); + first_run = TRUE; + } + } + return seconds; +} +//------------------------------------------------------------------------------ +/** \brief Cleans string and check if this is a proper directory path. + * + * @param string gchar** it is pointer to string which we want to check + * if it is proper directory/file path + * @return gchar* this is cleaned string (without filename at the end, + * spaces etc.) or NULL if passed string under pointer do not describe existing + * directory/file. On to this string points also passed pointer. + * + */ +static gchar* string_to_path(gchar** string) +{ + eg_debug("-> %s()\n-->PARAM:string=%s\n",__FUNCTION__,string[0]); + + gchar* arg = string[0]; + gchar* new = NULL; + // cleaning from leading and trailing whitespaces + g_strstrip(arg); + // add current directory if this is not absolute directory + if (!g_path_is_absolute(arg)) + { + gchar* tmp = g_get_current_dir(); + new = g_strconcat(tmp,"/",arg,NULL); + g_free(arg); arg = new; new = NULL; + }; + // this is not a directory + if (!g_file_test(arg, G_FILE_TEST_IS_DIR)) + { + // if this is wrong filepath, string was wrong + if (!g_file_test(arg, G_FILE_TEST_IS_REGULAR)) + { + g_free(arg); + new = NULL; + } + //if this is a file, remove filename + else + { + new = g_path_get_dirname (arg); + g_free(arg); + } + } + // this is a directory + else + { + // remove suffix "/" if neded... + if (g_str_has_suffix(arg,"/") ) + { + new = g_path_get_dirname (arg); + g_free(arg); + } + else + { + new = arg; + } + }; + // now in new should be proper filepath, if not, string was wrong + if (!g_file_test(new, G_FILE_TEST_IS_DIR)) + { + // if that directory does not exist, passed string wasn't proper + g_free(new); + new = NULL; + }; + // replace string under passed address + string[0] = new; + eg_debug("<- %s() returned string=%s\n",__FUNCTION__,string[0]); + return new; +} +//------------------------------------------------------------------------------ +/** \brief Get full filename (with path) to the icon file for this dictionary + * + * @param engine Engine* pointer to engine to which we want to get icon + * @return gchar* string containing full filepath with filename to icon + * file. If auto_free=FALSE of engine You should free this string if you do not + * need it any more. If auto_free is set to TRUE you should remember to not + * modyfing returned string! + */ +gchar* sd_engine_get_icon_path(Engine* engine) +{ + eg_debug("-> %s\n",__FUNCTION__); + + gchar* result; + SDData* data = (SDData*)(engine->engine_data); + if(data->auto_free) + { + result = data->icon; + } + else + { + result = g_strdup(data->icon); + } + + eg_debug("<- %s return string = \"%s\"\n",__FUNCTION__,result); + return result; +} +//------------------------------------------------------------------------------ +/** \brief Function not supported. + */ +gboolean sd_engine_add_word(Engine* engine, gchar* word, gchar* translation) +{ + eg_debug("<->%s Operation not supported in this engine\n",__FUNCTION__); + return FALSE; +} +//------------------------------------------------------------------------------ +/** \brief Function not supported. + */ +gboolean sd_engine_remove_word(Engine* engine, gchar* word) +{ + eg_debug("<->%s Operation not supported in this engine\n",__FUNCTION__); + return FALSE; +} +//------------------------------------------------------------------------------ +/** \brief Get language FROM which this dictionary translates. + * + * @param engine Engine* to check + */ +gchar* sd_engine_get_lang_from(Engine* engine) +{ + eg_debug("-> %s\n",__FUNCTION__); + + gchar* result; + SDData* data = (SDData*)(engine->engine_data); + if(data->auto_free) + { + result = data->lang_from; + } + else + { + result = g_strdup(data->lang_from); + } + + eg_debug("<- %s return string = \"%s\"\n",__FUNCTION__,result); + return result; +} +//------------------------------------------------------------------------------ +/** \brief Get language TO which this dictionary translates. + * + * @param engine Engine* to check + */ +gchar* sd_engine_get_lang_to(Engine* engine) +{ + eg_debug("-> %s\n",__FUNCTION__); + + gchar* result; + SDData* data = (SDData*)(engine->engine_data); + if(data->auto_free) + { + result = data->lang_to; + } + else + { + result = g_strdup(data->lang_to); + } + + eg_debug("<- %s return string = \"%s\"\n",__FUNCTION__,result); + return result; +} +//------------------------------------------------------------------------------ +/** \brief Gets title of dictionary. + * + * @param engine Engine* which title we want to get + */ +gchar* sd_engine_get_title(Engine* engine) +{ + eg_debug("-> %s\n",__FUNCTION__); + + gchar* result; + SDData* data = (SDData*)(engine->engine_data); + if(data->auto_free) + { + result = data->title; + } + else + { + result = g_strdup(data->title); + } + + eg_debug("<- %s return string = \"%s\"\n",__FUNCTION__,result); + return result; +} +//------------------------------------------------------------------------------ +/** \brief Sets callbacks for this dictionary. + * + * @param engine Engine*which callback we want to set + * @param signal gchar* define which callback we want to set + * @param c_handler gpointer function which we want to handle signal + * callback + * @param user_data gpointer which will be passed always as a argument + * to callback + * \sa dict_eng_set_callback + */ +gpointer sd_engine_set_callback(Engine* engine, + gchar* signal, + gpointer c_handler, + gpointer user_data) +{ + eg_debug("-> %s().\n",__FUNCTION__); + g_assert(engine != NULL); + g_assert(signal != NULL); + g_assert(c_handler != NULL); + SDData* data = (SDData*)(engine->engine_data); + if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) + { + gpointer result = data->cb_progress_caching; + data->cb_progress_caching = c_handler; + data->cb_progress_caching_data = user_data; + eg_debug("---> %s() sets handler for signal \"%s\".\n", + __FUNCTION__, + signal + ); + eg_debug("---> %s() Function at adress = %p.\n", + __FUNCTION__, + c_handler + ); + eg_debug("---> %s() Data at adress = %p.\n", + __FUNCTION__, + user_data + ); + eg_debug("<- %s().\n",__FUNCTION__); + return result; + } + else if(g_ascii_strcasecmp(signal, ENGINE_WORD_LIST_SIGNAL) == 0) + { + gpointer result = data->cb_search_word_list; + data->cb_search_word_list = c_handler; + data->cb_search_word_list_data = user_data; + eg_debug("---> %s() sets handler for signal \"%s\".\n", + __FUNCTION__, + signal + ); + eg_debug("---> %s() Function at adress = %p.\n", + __FUNCTION__, + c_handler + ); + eg_debug("---> %s() Data at adress = %p.\n", + __FUNCTION__, + user_data + ); + eg_debug("<- %s().\n",__FUNCTION__); + return result; + } + else if(g_ascii_strcasecmp(signal, ENGINE_WORD_TRANSLATION_SIGNAL) == 0) + { + gpointer result = data->cb_search_word_trans; + data->cb_search_word_trans = c_handler; + data->cb_search_word_trans_data = user_data; + eg_debug("---> %s() sets handler for signal \"%s\".\n", + __FUNCTION__, + signal + ); + eg_debug("---> %s() Function at adress = %p.\n", + __FUNCTION__, + c_handler + ); + eg_debug("---> %s() Data at adress = %p.\n", + __FUNCTION__, + user_data + ); + eg_debug("<- %s().\n",__FUNCTION__); + return result; + } + else + { + eg_warning("---> %s() unsupported signal: %s.\n", + __FUNCTION__, + signal + ); + eg_debug("<- %s().\n",__FUNCTION__); + return NULL; + } +} +//------------------------------------------------------------------------------ +// for macro: dict_eng_set_progress_seed(engine, signal, val) +/** \brief Sets how often should be called concrete progress calback. + * + * @param engine Engine* for which we want set seed for progress proccess + * @param signal gchar* for which we want to set seed + * @param seed gdouble which we want to set + */ +void sd_engine_set_progress_seed(Engine* engine, gchar* signal, gdouble seed) +{ + eg_debug("-> %s().\n",__FUNCTION__); + SDData* data = (SDData*)(engine->engine_data); + if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) + { + data->cb_progress_caching_seed = seed; + eg_debug("--->%s() sets new seed=%0.2f for for signal %s.\n", + __FUNCTION__, + seed, + signal + ); + } + else + { + g_warning("--->%s() unsupported signal for progress: %s.\n", + __FUNCTION__, + signal + ); + }; + eg_debug("<- %s().\n",__FUNCTION__); +} +//------------------------------------------------------------------------------ +/** \brief Get the last status of engine. + * + * @param engine Engine* which status we want to get + * @return EngineStatus status of the engine + * \sa dict_eng_get_last_status + */ +EngineStatus sd_engine_status(Engine* engine) +{ + eg_debug("-> %s()\n--->PARAM:engine at adress=%p\n", + __FUNCTION__, + engine + ); + SDData* data = (SDData*)(engine->engine_data); + eg_debug("<- %s() returned error code: %d\n", + __FUNCTION__, + (gint)(data->last_error) + ); + return data->last_error; +} +//------------------------------------------------------------------------------ +/** \brief Tells if engine is optimized or not - not supported in StarDict. + */ +gboolean sd_engine_is_optimized(Engine* engine) +{ + eg_debug("-> %s() for engine at adress=%p\n", + __FUNCTION__, + engine + ); + g_assert(engine != NULL); + + gboolean result = TRUE; + + eg_debug("<- %s() returned bool statement=%s.\n", + __FUNCTION__, + PRINT_STATE(result) + ); + return result; +} +//------------------------------------------------------------------------------ +/** \brief Optimize dictionary - not supported in StarDict dictionaries. + */ +void sd_engine_optimize(Engine* engine) +{ + eg_debug("-> %s() called for engine at adress=%p\n", + __FUNCTION__, + engine + ); + eg_debug("---> Unsupported method for this engine\n"); + eg_debug("<- %s()\n",__FUNCTION__); +} +//------------------------------------------------------------------------------ +/** \brief Get structure and access to all module functions. + * + * @return EngineModule structure containing all functions which are + * needed to handle new dictionary's format + */ +EngineModule engine_global_functions() +{ + eg_debug("-> %s() called.\n",__FUNCTION__); + EngineModule result; + result.engine_check = sd_engine_check; + result.engine_description= sd_engine_description; + result.engine_format = sd_engine_format; + result.engine_version = sd_engine_version; + result.engine_create = sd_engine_create; + eg_debug("<- %s() returned EngineModule at adress=%p.\n", + __FUNCTION__, + &result + ); + return result; +} +//------------------------------------------------------------------------------ +/** \brief Translate status code to meaningful, human-readable information. + * + * @param status EngineStatus to translates + * @return gchar* message describing status (e.g. its reason etc.) + * \sa dict_eng_status_message + */ +gchar* sd_engine_status_message(EngineStatus status) +{ + eg_debug("<-> %s() called.\n",__FUNCTION__); + switch (status) + { + case ENGINE_NO_ERROR: + return "No error."; + case ENGINE_WRONG_FILE: + return "File, You are trying to use, is wrong type."; + case ENGINE_COULDNT_READ: + return "Could not read from file."; + case ENGINE_NO_FILE: + return "There is no such a file."; + case ENGINE_OUT_OF_MEMORY: + return "There were no enough memory for this action."; + default: + return "Wrong engine's status identifier!"; + } +} +//------------------------------------------------------------------------------ +/** \brief Gets version of module. + * @return gchar* version of this module. + * \sa dict_eng_module_get_version + */ +gchar* sd_engine_version() +{ + eg_debug("-> %s()\n",__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_VERSION); + eg_debug("<- %s() return string=%s\n", + __FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +/** \brief Get information about what kind of dictionaries this engine support. + * + * @return gchar* telling about supported dictionaries (e.g. XDXF, + * StarDict etc.) + * \sa dict_eng_module_get_format + */ +gchar* sd_engine_format() +{ + eg_debug("-> %s()\n",__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_FORMAT); + eg_debug("<- %s() return string=%s\n", + __FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +/** \brief Get short description of the module - dictionary engine. + * + * @return gchar* description of the module + * \sa dict_eng_module_get_description + */ +gchar* sd_engine_description() +{ + eg_debug("-> %s()\n",__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_DESCRIPTION); + eg_debug("<- %s() return string=%s\n", + __FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +/** \brief Get path to the dictionary - location of its files. + * + * @param engine Engine* which directory path we want to get + * @return gchar* location of the dictionary + * \sa dict_eng_get_location + */ +gchar* sd_engine_location(Engine* engine) +{ + eg_debug("->%s() called.\n-->PARAM: engine adress=%p\n", + __FUNCTION__, + engine + ); + g_assert(engine != NULL); + SDData* data = (SDData*)(engine->engine_data); + + gchar* result; + if(data->auto_free) + { + result = data->dict_path; + } + else + { + result = g_strdup(data->dict_path); + } + + eg_debug("<- %s() returned string=%s\n", + __FUNCTION__, + result + ); + return result; +} +//------------------------------------------------------------------------------ +/** \brief Set auto free status for engine. + * + * When auto flag is set to TRUE, user of engine do not have to worry about + * freeing any of buffer returned by the engine. Engine will clean up + * everything. When auto free is set as FALSE, user has to remember that every- + * thing returned from engine should be deallocated. + * + * @param engine Engine* which auto free flag we want to sets + * @param state gboolean new value for auto free flag + * \sa dict_eng_set_auto_free + */ +void sd_engine_set_auto_free(Engine* engine, gboolean state) +{ + eg_debug("-> %s()\n" + "--->PARAM:engine at adress=%p\n--->PARAM:state=%s\n", + __FUNCTION__, + engine, + PRINT_STATE(state) + ); + g_assert(engine != NULL); + SDData* data = (SDData*)(engine->engine_data); + + data->auto_free = state; + eg_debug("<- %s() Current auto_free is %s\n", + __FUNCTION__, + PRINT_STATE(data->auto_free) + ); +} +//------------------------------------------------------------------------------ +/** \brief Parse single record from *.ifo file from StarDict dictionary + * + * @param data SDData* structure which we will try to complete with + * information from new record + * @param key gchar* string representing key of record + * @param value gchar* value of the key in record + */ +void sd_parse_record(SDData* data,gchar* key, gchar* value) +{ + if(g_ascii_strncasecmp(key,"version",100) == 0) + { + } + else if(g_ascii_strncasecmp(key,"bookname",100) == 0) + { + data->title = g_strdup(value); + eg_debug("%s set title to: %s\n",__FUNCTION__, data->title); + } + else if(g_ascii_strncasecmp(key,"wordcount",100) == 0) + { + data->word_count = (gint)g_ascii_strtoull( value, NULL, 10); + eg_debug("%s set word count to: %d\n", + __FUNCTION__, + data->word_count + ); + } + else if(g_ascii_strncasecmp(key,"idxfilesize",100) == 0) + { + data->idx_file_length = (gint)g_ascii_strtoull(value, NULL, 10); + eg_debug("%s set idx file length to: %d\n", + __FUNCTION__, + data->idx_file_length + ); + } + else if(g_ascii_strncasecmp(key,"sametypesequence",100) == 0) + { + data->types = g_strdup(value); + eg_debug("%s set data types to: %s\n",__FUNCTION__,data->types); + } + else + { + eg_debug("%s trying to set usupported field\n",__FUNCTION__); + } + /* ----- as far unsupported field from *.ifo files + else if(g_ascii_strncasecmp(key,"author",100)) + { + } + else if(g_ascii_strncasecmp(key,"email",100)) + { + } + else if(g_ascii_strncasecmp(key,"website",100)) + { + } + else if(g_ascii_strncasecmp(key,"description",100)) + { + } + else if(g_ascii_strncasecmp(key,"date",100)) + { + } */ +} +//------------------------------------------------------------------------------ +/** \brief Try to read and parse whole *.ifo file from StarDict Dictionary + * + * @param data SDData* structure to which we try save information about + * dictionary in data->dict_path path + * @return gboolean if data->dict_path is good path and it contains all + * obligatory StarDict files, function return TRUE. Otherwise return FALSE. + */ +gboolean sd_parse_ifo_file(SDData* data) +{ + GnomeVFSHandle* fd = NULL; + GnomeVFSResult fr = 0; + GnomeVFSFileSize n = 0; + GnomeVFSFileSize k = 0; + + if(!gnome_vfs_initialized ()) + { + gnome_vfs_init (); + }; + // open the file + fr = gnome_vfs_open (&fd, data->ifo_file_name, GNOME_VFS_OPEN_READ); + if(fr != GNOME_VFS_OK) + { + eg_warning("Error while trying to open file:\n%s\n", + data->ifo_file_name + ); + return FALSE; + } + gnome_vfs_seek(fd, GNOME_VFS_SEEK_END, 0); + fr = gnome_vfs_tell(fd, &n); + gnome_vfs_seek(fd, GNOME_VFS_SEEK_START, 0); + // read whole content + gchar* tmp = g_try_malloc0(sizeof(gchar)*((gint)(n))); + fr = gnome_vfs_read(fd, tmp, n, &k); + if(fr != GNOME_VFS_OK) { + eg_warning("Error while trying to read file:\n%s\n", + data->ifo_file_name + ); + gnome_vfs_close(fd); + return FALSE; + } + gnome_vfs_close(fd); + // now we have in tmp whole content of file, we have to "parse it" + gchar** table = g_strsplit(tmp, "\n", 100); + gint i; + for(i=0; table[i]!=NULL; ++i) + { + gchar* eq = g_strstr_len (table[i], 0xffff, "="); + if(eq == NULL) continue; + *eq = '\0'; + ++eq; + eg_debug("SD *.ifo record -> Key=%s => Value=%s\n",table[i],eq); + sd_parse_record(data, table[i], eq); + } + + g_free(tmp); tmp = NULL; + g_strfreev(table); table = NULL; + if(data->title) + { + return TRUE; + } + else + { + return FALSE; + } +} +//------------------------------------------------------------------------------ +//-------------------------------------------------------------- STANDARD ------ +//------------------------------------------------------------------------------ +/** \brief Opening file not compressed + * + * @param filename gchar* full filename (with path) to file to open + * @return gpointer pointer to memory which is needed for other functions + * from this wrapper. Under this pointer could be simple gint or more + * complicated structure - depends on what kind of file we are trying to open. + * If opening failed - function return NULL. + */ +static gpointer sd_open(gchar* filename) +{ + gint tmp = open(filename, O_RDONLY); + if(tmp == -1) + { + eg_debug("---> Error while trying to open file %s\n",filename); + return NULL; + } + gint* result = (int*)g_try_malloc0(sizeof(gint)); + *result = tmp; + return (gpointer)result; +} +//------------------------------------------------------------------------------ +/** \brief Reading from not compressed file + * + * @param f gpointer pointer returned from sd_open() + * @param buffer gchar* buffer where data should be put after reading + * @param l gint maximum bytes to read. Effective number of bytes readed + * could be different from this argument and is returned from function. + * @return gint effective number of readed bytes + */ +static gint sd_read(gpointer f, gchar* buffer, gint l) +{ + gint tmp = *((gint*)(f)); + return (gint)read(tmp, buffer, l); +} +//------------------------------------------------------------------------------ +/** \brief Seek throught not compressed files + * + * @param f gpointer pointer returned from sd_open() + * @param l glong offset which we want to seek + * @param from gchar postion from which we want to seek. Possible values + * are:\n _FILES_WRAPPER_BEG for the beggining of file \n + * _FILES_WRAPPER_CUR for the current position \n + * _FILES_WRAPPER_END for the end of file. + * @return glong previous position in file if operation was successful, + * or non positive value if there was an error. + */ +static glong sd_seek(gpointer f, glong l, gchar from) +{ + gint tmp = *((gint*)(f)); + switch(from) + { + case _FILES_WRAPPER_BEG: + return (glong)lseek(tmp, l, SEEK_SET); + case _FILES_WRAPPER_CUR: + return (glong)lseek(tmp, l, SEEK_CUR); + case _FILES_WRAPPER_END: + return (glong)lseek(tmp, l, SEEK_END); + default: + eg_debug("---> Wrong relative position for sd_seek!\n"); + return -2; + } +} +//------------------------------------------------------------------------------ +/** \brief Close uncompressed file + * + * @param f gpointer pointer returned from sd_open() - file to close. + */ +static void sd_close(gpointer f) +{ + gint tmp = *((gint*)(f)); + close(tmp); +} +//------------------------------------------------------------------------------ +//------------------------------------------------------- GZIPPED -------------- +//------------------------------------------------------------------------------ +/** \brief Opening file compressed with standard gzip + * + * @param filename gchar* full filename (with path) to file to open + * @return gpointer pointer to memory which is needed for other functions + * from this wrapper. Under this pointer could be simple gint or more + * complicated structure - depends on what kind of file we are trying to open. + * If opening failed - function return NULL. + */ +static gpointer sd_open_z(gchar* filename) +{ + gzFile* out = (gzFile*)g_try_malloc0(sizeof(gzFile)); + *out = gzopen(filename, "rb9"); + if(out == NULL) + { + eg_debug("Error while opening compressed file with gzip!\n"); + } + return (gpointer)out; +} +//------------------------------------------------------------------------------ +/** \brief Reading from compressed file with gzip + * + * @param f gpointer pointer retunred from sd_open() + * @param buffer gchar* buffer where data should be put after reading + * @param l gint maximum bytes to read. Effective number of bytes readed + * could be different from this argument and is returned from function. + * @return gint effective number of readed bytes + */ +static gint sd_read_z(gpointer f, gchar* buffer, gint l) +{ + gzFile tmp = *((gzFile*)f); + return (gint)gzread(tmp, buffer, l); +} +//------------------------------------------------------------------------------ +/** \brief Seek throught compressed files with gzip + * + * @param f gpointer pointer returned from sd_open() + * @param l glong offset which we want to seek + * @param from gchar postion from which we want to seek. Possible values + * are:\n _FILES_WRAPPER_BEG for the beggining of file \n + * _FILES_WRAPPER_CUR for the current position \n + * _FILES_WRAPPER_END for the end of file. + * @return glong previous position in file if operation was successful, + * or non positive value if there was an error. + */ +static glong sd_seek_z(gpointer f, glong l, gchar from) +{ + gzFile tmp = *((gzFile*)f); + switch(from) + { + case _FILES_WRAPPER_BEG: + return (glong)gzseek(tmp, l, SEEK_SET); + case _FILES_WRAPPER_CUR: + return (glong)gzseek(tmp, l, SEEK_CUR); + default: + eg_debug("---> Wrong position for sd_seek_z!\n"); + return -2; + } +} +//------------------------------------------------------------------------------ +/** \brief Close compressed file with gzip + * + * @param f gpointer pointer returned from sd_open() - file to close. + */ +static void sd_close_z(gpointer f) +{ + gzFile tmp = *((gzFile*)f); + gzclose(tmp); +} diff --git a/src/plugins/stardict/src/test.c b/src/plugins/stardict/src/test.c new file mode 100755 index 0000000..0239d5b --- /dev/null +++ b/src/plugins/stardict/src/test.c @@ -0,0 +1,133 @@ +/******************************************************************************* +This file is part of WhiteStork. + +WhiteStork 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. + +WhiteStork 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 WhiteStork; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright 2006 ComArch S.A. +*******************************************************************************/ +#include +#include +#include +#include + +#define DICT_PATH0 "/home/str/whitestork/stardictDicts/stardict-comn_dictd03_slovnyk_pl-ru-2.4.2" +#define DICT_PATH1 "/home/str/whitestork/stardictDicts/stardict-comn_dictd03_slovnyk_pl-en-2.4.2" +#define DICT_PATH2 "/home/str/whitestork/stardictDicts/stardict-dictd_www.dict.org_foldoc-2.4.2" +#define DICT_PATH3 "/home/str/whitestork/stardictDicts/stardict-dictd_www.freedict.de_eng-fra-2.4.2" +#define DICT_PATH4 "/home/gandzia/MyDocs/.documents/stardict-comn_dictd03_engcom-2.4.2" +#define DICT_PATH5 "/home/lukasz/MyDocs/stardict-foldoc" +#define DICT_PATH6 + + +#define DICT_PATH DICT_PATH5 + +gchar* dictionaries[] = { + DICT_PATH0, + DICT_PATH1, + DICT_PATH2, + DICT_PATH3, + NULL +}; + +getting_additional get_functions; // additional functions for concrete module (e.g. XDXF) + +void print_list(GArray* list, gchar* pattern, gpointer user_data, EngineStatus error) { + printf((gchar*)user_data,pattern); + int i = 0; + while(g_array_index(list, gchar*, i) != NULL) + { + printf(" %d. : %s\n",i+1,g_array_index(list, gchar*, i)); + i++; + } + +} + +void print_translation(gchar* translation, gchar* word, gpointer user_data, EngineStatus error) { + printf((gchar*)user_data,word); + printf("%s\n\nTRANSLATION ENDS.\n",translation); +} + +void caching_progress(gdouble value, gpointer user_data, EngineStatus error) { + printf((gchar*)user_data,value); +} + +int main(int argc, char** argv) +{ + char* nameApp = "StarDictEngine test: "; + printf("%sStarting test program of module: dictionary_engine - StarDict\n",nameApp); + + + gchar* current_directory = g_get_current_dir(); + printf("%sCurrent directory: %s\n",nameApp,current_directory); + gchar* library_to_path = g_strconcat(current_directory, "/bin/engine_stardict.so", NULL); + printf("%sEngine library should be in location:\n\t%s\n",nameApp,library_to_path); + + GModule *library = g_module_open(library_to_path, G_MODULE_BIND_LAZY); + if(!library) + { + printf("%sLoading module failed. \nReason: %s\n",nameApp,g_module_error()); + return 1; + }; + + g_module_symbol ( (library),_GLOBAL_FUNCTIONS_NAME_, (gpointer)&get_functions); + if(get_functions == NULL) + { + printf("%sLoading function failed\n",nameApp); + return 2; + } + else + { + printf("%sLoading function OK\n",nameApp); + } + + EngineModule module = get_functions(); + printf("Module description: %s\n",dict_eng_module_get_description(module)); + Engine* sd; + + gboolean is_compatible = dict_eng_module_check(module, DICT_PATH); + if(is_compatible == TRUE) + { + printf("Location is compatible with enigne!\n"); + } + else { + printf("Location is not compatible with enigne!\n"); + return 1; + } + + + sd = dict_eng_module_create(module, DICT_PATH, ENGINE_NO); + printf("Searching in dictionary: \'%s\'\n",dict_eng_get_title(sd)); + dict_eng_set_callback(sd, + ENGINE_WORD_LIST_SIGNAL, + print_list, + "Word list matches to pattern: %s\n" + ); + dict_eng_set_callback(sd, + ENGINE_WORD_TRANSLATION_SIGNAL , + print_translation, + "Translation for word\'%s\':\n" + ); + + dict_eng_search_word_list(sd,"a"); + dict_eng_search_word_list(sd,"z"); + dict_eng_search_word_translation(sd,"deb"); + dict_eng_search_word_translation(sd,"abort"); + + + dict_eng_destroy(sd); + printf("%sClosed.\n",nameApp); + return 0; +} + diff --git a/src/plugins/stardict/test_dictsip/data.c b/src/plugins/stardict/test_dictsip/data.c new file mode 100644 index 0000000..1463d05 --- /dev/null +++ b/src/plugins/stardict/test_dictsip/data.c @@ -0,0 +1,524 @@ +/* data.c -- + * Created: Tue Jul 16 12:45:41 1996 by faith@dict.org + * Revised: Sat Mar 30 10:46:06 2002 by faith@dict.org + * Copyright 1996, 1997, 1998, 2000, 2002 Rickard E. Faith (faith@dict.org) + * + * 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 1, 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: data.c,v 1.24 2004/10/12 12:55:14 cheusov Exp $ + * + */ + +#include "dictP.h" + +#include "data.h" +#include "dictzip.h" + +#include +#ifdef HAVE_MMAP +#include +#endif +#include +#include +#include +#ifdef HAVE_MMAP +#include +#endif + +#define USE_CACHE 1 + +#ifdef HAVE_MMAP +int mmap_mode = 1; /* dictd uses mmap() function (the default) */ +#else +int mmap_mode = 0; +#endif + +int dict_data_filter( char *buffer, int *len, int maxLength, + const char *filter ) +{ + char *outBuffer; + int outLen; + + if (!filter) return 0; + outBuffer = xmalloc( maxLength + 2 ); + + outLen = pr_filter( filter, buffer, *len, outBuffer, maxLength + 1 ); + if (outLen > maxLength ) + err_fatal( __FUNCTION__, + "Filter grew buffer from %d past limit of %d\n", + *len, maxLength ); + memcpy( buffer, outBuffer, outLen ); + xfree( outBuffer ); + + PRINTF(DBG_UNZIP|DBG_ZIP,("Length was %d, now is %d\n",*len,outLen)); + + *len = outLen; + + return 0; +} + +static int dict_read_header( const char *filename, + dictData *header, int computeCRC ) +{ + FILE *str; + int id1, id2, si1, si2; + char buffer[BUFFERSIZE]; + int extraLength, subLength; + int i; + char *pt; + int c; + struct stat sb; + unsigned long crc = crc32( 0L, Z_NULL, 0 ); + int count; + unsigned long offset; + + if (!(str = fopen( filename, "r" ))) + err_fatal_errno( __FUNCTION__, + "Cannot open data file \"%s\" for read\n", filename ); + + header->filename = str_find( filename ); + header->headerLength = GZ_XLEN - 1; + header->type = DICT_UNKNOWN; + + id1 = getc( str ); + id2 = getc( str ); + + if (id1 != GZ_MAGIC1 || id2 != GZ_MAGIC2) { + header->type = DICT_TEXT; + fstat( fileno( str ), &sb ); + header->compressedLength = header->length = sb.st_size; + header->origFilename = str_find( filename ); + header->mtime = sb.st_mtime; + if (computeCRC) { + rewind( str ); + while (!feof( str )) { + if ((count = fread( buffer, 1, BUFFERSIZE, str ))) { + crc = crc32( crc, buffer, count ); + } + } + } + header->crc = crc; + fclose( str ); + return 0; + } + header->type = DICT_GZIP; + + header->method = getc( str ); + header->flags = getc( str ); + header->mtime = getc( str ) << 0; + header->mtime |= getc( str ) << 8; + header->mtime |= getc( str ) << 16; + header->mtime |= getc( str ) << 24; + header->extraFlags = getc( str ); + header->os = getc( str ); + + if (header->flags & GZ_FEXTRA) { + extraLength = getc( str ) << 0; + extraLength |= getc( str ) << 8; + header->headerLength += extraLength + 2; + si1 = getc( str ); + si2 = getc( str ); + + if (si1 == GZ_RND_S1 && si2 == GZ_RND_S2) { + subLength = getc( str ) << 0; + subLength |= getc( str ) << 8; + header->version = getc( str ) << 0; + header->version |= getc( str ) << 8; + + if (header->version != 1) + err_internal( __FUNCTION__, + "dzip header version %d not supported\n", + header->version ); + + header->chunkLength = getc( str ) << 0; + header->chunkLength |= getc( str ) << 8; + header->chunkCount = getc( str ) << 0; + header->chunkCount |= getc( str ) << 8; + + if (header->chunkCount <= 0) { + fclose( str ); + return 5; + } + header->chunks = xmalloc( sizeof( header->chunks[0] ) + * header->chunkCount ); + for (i = 0; i < header->chunkCount; i++) { + header->chunks[i] = getc( str ) << 0; + header->chunks[i] |= getc( str ) << 8; + } + header->type = DICT_DZIP; + } else { + fseek( str, header->headerLength, SEEK_SET ); + } + } + + if (header->flags & GZ_FNAME) { /* FIXME! Add checking against header len */ + pt = buffer; + while ((c = getc( str )) && c != EOF){ + *pt++ = c; + + if (pt == buffer + sizeof (buffer)){ + err_fatal ( + __FUNCTION__, + "too long FNAME field in dzip file \"%s\"\n", filename); + } + } + + *pt = '\0'; + header->origFilename = str_find( buffer ); + header->headerLength += strlen( header->origFilename ) + 1; + } else { + header->origFilename = NULL; + } + + if (header->flags & GZ_COMMENT) { /* FIXME! Add checking for header len */ + pt = buffer; + while ((c = getc( str )) && c != EOF){ + *pt++ = c; + + if (pt == buffer + sizeof (buffer)){ + err_fatal ( + __FUNCTION__, + "too long COMMENT field in dzip file \"%s\"\n", filename); + } + } + + *pt = '\0'; + header->comment = str_find( buffer ); + header->headerLength += strlen( header->comment ) + 1; + } else { + header->comment = NULL; + } + + if (header->flags & GZ_FHCRC) { + getc( str ); + getc( str ); + header->headerLength += 2; + } + + if (ftell( str ) != header->headerLength + 1) + err_internal( __FUNCTION__, + "File position (%lu) != header length + 1 (%d)\n", + ftell( str ), header->headerLength + 1 ); + + fseek( str, -8, SEEK_END ); + header->crc = getc( str ) << 0; + header->crc |= getc( str ) << 8; + header->crc |= getc( str ) << 16; + header->crc |= getc( str ) << 24; + header->length = getc( str ) << 0; + header->length |= getc( str ) << 8; + header->length |= getc( str ) << 16; + header->length |= getc( str ) << 24; + header->compressedLength = ftell( str ); + + /* Compute offsets */ + header->offsets = xmalloc( sizeof( header->offsets[0] ) + * header->chunkCount ); + for (offset = header->headerLength + 1, i = 0; + i < header->chunkCount; + i++) + { + header->offsets[i] = offset; + offset += header->chunks[i]; + } + + fclose( str ); + return 0; +} + +dictData *dict_data_open( const char *filename, int computeCRC ) +{ + dictData *h = NULL; + struct stat sb; + int j; + + if (!filename) + return NULL; + + h = xmalloc( sizeof( struct dictData ) ); + + memset( h, 0, sizeof( struct dictData ) ); + h->initialized = 0; + + if (stat( filename, &sb ) || !S_ISREG(sb.st_mode)) { + err_warning( __FUNCTION__, + "%s is not a regular file -- ignoring\n", filename ); + return h; + } + + if (dict_read_header( filename, h, computeCRC )) { + err_fatal( __FUNCTION__, + "\"%s\" not in text or dzip format\n", filename ); + } + + if ((h->fd = open( filename, O_RDONLY )) < 0) + err_fatal_errno( __FUNCTION__, + "Cannot open data file \"%s\"\n", filename ); + if (fstat( h->fd, &sb )) + err_fatal_errno( __FUNCTION__, + "Cannot stat data file \"%s\"\n", filename ); + h->size = sb.st_size; + + if (mmap_mode){ +#ifdef HAVE_MMAP + h->start = mmap( NULL, h->size, PROT_READ, MAP_SHARED, h->fd, 0 ); + if ((void *)h->start == (void *)(-1)) + err_fatal_errno( + __FUNCTION__, + "Cannot mmap data file \"%s\"\n", filename ); +#else + err_fatal (__FUNCTION__, "This should not happen"); +#endif + }else{ + h->start = xmalloc (h->size); + if (-1 == read (h->fd, (char *) h->start, h->size)) + err_fatal_errno ( + __FUNCTION__, + "Cannot read data file \"%s\"\n", filename ); + + close (h -> fd); + h -> fd = 0; + } + + h->end = h->start + h->size; + + for (j = 0; j < DICT_CACHE_SIZE; j++) { + h->cache[j].chunk = -1; + h->cache[j].stamp = -1; + h->cache[j].inBuffer = NULL; + h->cache[j].count = 0; + } + + return h; +} + +void dict_data_close( dictData *header ) +{ + int i; + + if (!header) + return; + + if (header->fd >= 0) { + if (mmap_mode){ +#ifdef HAVE_MMAP + munmap( (void *)header->start, header->size ); + close( header->fd ); + header->fd = 0; + header->start = header->end = NULL; +#else + err_fatal (__FUNCTION__, "This should not happen"); +#endif + }else{ + if (header -> start) + xfree ((char *) header -> start); + } + } + + if (header->chunks) xfree( header->chunks ); + if (header->offsets) xfree( header->offsets ); + + if (header->initialized) { + if (inflateEnd( &header->zStream )) + err_internal( __FUNCTION__, + "Cannot shut down inflation engine: %s\n", + header->zStream.msg ); + } + + for (i = 0; i < DICT_CACHE_SIZE; ++i){ + if (header -> cache [i].inBuffer) + xfree (header -> cache [i].inBuffer); + } + + memset( header, 0, sizeof( struct dictData ) ); + xfree( header ); +} + +char *dict_data_obtain (const dictDatabase *db, const dictWord *dw) +{ + char *word_copy; + int len; + + if (!dw || !db) + return NULL; + + if (dw -> def){ + if (-1 == dw -> def_size){ + len = strlen (dw -> def); + }else{ + len = dw -> def_size; + } + + word_copy = xmalloc (2 + len); + memcpy (word_copy, dw -> def, len); + word_copy [len + 0] = '\n'; + word_copy [len + 1] = 0; + + return word_copy; + }else{ + assert (db); + assert (db -> data); + + return dict_data_read_ ( + db -> data, dw -> start, dw -> end, + db->prefilter, db->postfilter); + } +} + +char *dict_data_read_ ( + dictData *h, unsigned long start, unsigned long size, + const char *preFilter, const char *postFilter ) +{ + char *buffer, *pt; + unsigned long end; + int count; + char *inBuffer; + char outBuffer[OUT_BUFFER_SIZE]; + int firstChunk, lastChunk; + int firstOffset, lastOffset; + int i, j; + int found, target, lastStamp; + static int stamp = 0; + + end = start + size; + + buffer = xmalloc( size + 1 ); + + PRINTF(DBG_UNZIP, + ("dict_data_read( %p, %lu, %lu, %s, %s )\n", + h, start, size, preFilter, postFilter )); + + assert( h != NULL); + switch (h->type) { + case DICT_GZIP: + err_fatal( __FUNCTION__, + "Cannot seek on pure gzip format files.\n" + "Use plain text (for performance)" + " or dzip format (for space savings).\n" ); + break; + case DICT_TEXT: + memcpy( buffer, h->start + start, size ); + buffer[size] = '\0'; + break; + case DICT_DZIP: + if (!h->initialized) { + ++h->initialized; + h->zStream.zalloc = NULL; + h->zStream.zfree = NULL; + h->zStream.opaque = NULL; + h->zStream.next_in = 0; + h->zStream.avail_in = 0; + h->zStream.next_out = NULL; + h->zStream.avail_out = 0; + if (inflateInit2( &h->zStream, -15 ) != Z_OK) + err_internal( __FUNCTION__, + "Cannot initialize inflation engine: %s\n", + h->zStream.msg ); + } + firstChunk = start / h->chunkLength; + firstOffset = start - firstChunk * h->chunkLength; + lastChunk = end / h->chunkLength; + lastOffset = end - lastChunk * h->chunkLength; + PRINTF(DBG_UNZIP, + (" start = %lu, end = %lu\n" + "firstChunk = %d, firstOffset = %d," + " lastChunk = %d, lastOffset = %d\n", + start, end, firstChunk, firstOffset, lastChunk, lastOffset )); + for (pt = buffer, i = firstChunk; i <= lastChunk; i++) { + + /* Access cache */ + found = 0; + target = 0; + lastStamp = INT_MAX; + for (j = 0; j < DICT_CACHE_SIZE; j++) { +#if USE_CACHE + if (h->cache[j].chunk == i) { + found = 1; + target = j; + break; + } +#endif + if (h->cache[j].stamp < lastStamp) { + lastStamp = h->cache[j].stamp; + target = j; + } + } + + h->cache[target].stamp = ++stamp; + if (found) { + count = h->cache[target].count; + inBuffer = h->cache[target].inBuffer; + } else { + h->cache[target].chunk = i; + if (!h->cache[target].inBuffer) + h->cache[target].inBuffer = xmalloc( IN_BUFFER_SIZE ); + inBuffer = h->cache[target].inBuffer; + + if (h->chunks[i] >= OUT_BUFFER_SIZE ) { + err_internal( __FUNCTION__, + "h->chunks[%d] = %d >= %ld (OUT_BUFFER_SIZE)\n", + i, h->chunks[i], OUT_BUFFER_SIZE ); + } + memcpy( outBuffer, h->start + h->offsets[i], h->chunks[i] ); + dict_data_filter( outBuffer, &count, OUT_BUFFER_SIZE, preFilter ); + + h->zStream.next_in = outBuffer; + h->zStream.avail_in = h->chunks[i]; + h->zStream.next_out = inBuffer; + h->zStream.avail_out = IN_BUFFER_SIZE; + if (inflate( &h->zStream, Z_PARTIAL_FLUSH ) != Z_OK) + err_fatal( __FUNCTION__, "inflate: %s\n", h->zStream.msg ); + if (h->zStream.avail_in) + err_internal( __FUNCTION__, + "inflate did not flush (%d pending, %d avail)\n", + h->zStream.avail_in, h->zStream.avail_out ); + + count = IN_BUFFER_SIZE - h->zStream.avail_out; + dict_data_filter( inBuffer, &count, IN_BUFFER_SIZE, postFilter ); + + h->cache[target].count = count; + } + + if (i == firstChunk) { + if (i == lastChunk) { + memcpy( pt, inBuffer + firstOffset, lastOffset-firstOffset); + pt += lastOffset - firstOffset; + } else { + if (count != h->chunkLength ) + err_internal( __FUNCTION__, + "Length = %d instead of %d\n", + count, h->chunkLength ); + memcpy( pt, inBuffer + firstOffset, + h->chunkLength - firstOffset ); + pt += h->chunkLength - firstOffset; + } + } else if (i == lastChunk) { + memcpy( pt, inBuffer, lastOffset ); + pt += lastOffset; + } else { + assert( count == h->chunkLength ); + memcpy( pt, inBuffer, h->chunkLength ); + pt += h->chunkLength; + } + } + *pt = '\0'; + break; + case DICT_UNKNOWN: + err_fatal( __FUNCTION__, "Cannot read unknown file type\n" ); + break; + } + + return buffer; +} diff --git a/src/plugins/stardict/test_dictsip/data.h b/src/plugins/stardict/test_dictsip/data.h new file mode 100644 index 0000000..0cd39da --- /dev/null +++ b/src/plugins/stardict/test_dictsip/data.h @@ -0,0 +1,56 @@ +/* data.h -- + * Created: Sat Mar 15 18:04:25 2003 by Aleksey Cheusov + * Copyright 1994-2003 Rickard E. Faith (faith@dict.org) + * + * 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 1, 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: data.h,v 1.1 2003/03/19 16:43:15 cheusov Exp $ + */ + +#ifndef _DATA_H_ +#define _DATA_H_ + +#include "dictP.h" +#include "defs.h" + +/* initialize .data file */ +extern dictData *dict_data_open ( + const char *filename, int computeCRC); +/* */ +extern void dict_data_close ( + dictData *data); + +extern void dict_data_print_header( FILE *str, dictData *data ); +extern int dict_data_zip( + const char *inFilename, const char *outFilename, + const char *preFilter, const char *postFilter ); + +extern char *dict_data_obtain ( + const dictDatabase *db, + const dictWord *dw); + +extern char *dict_data_read_ ( + dictData *data, + unsigned long start, unsigned long end, + const char *preFilter, + const char *postFilter ); + +extern int dict_data_filter( + char *buffer, int *len, int maxLength, + const char *filter ); + +extern int mmap_mode; + +#endif /* _DATA_H_ */ diff --git a/src/plugins/stardict/test_dictsip/dictd.c b/src/plugins/stardict/test_dictsip/dictd.c new file mode 100644 index 0000000..64a9edc --- /dev/null +++ b/src/plugins/stardict/test_dictsip/dictd.c @@ -0,0 +1,1962 @@ +/* dictd.c -- + * Created: Fri Feb 21 20:09:09 1997 by faith@dict.org + * Revised: Sat May 4 21:58:16 2002 by faith@dict.org + * Copyright 1997-2000, 2002 Rickard E. Faith (faith@dict.org) + * + * 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 1, 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: dictd.c,v 1.124 2005/04/14 07:52:16 cheusov Exp $ + * + */ + +#include "dictd.h" +#include "str.h" + +#include "servparse.h" +#include "strategy.h" +#include "index.h" +#include "data.h" +#include "parse.h" + +#ifdef USE_PLUGIN +#include "plugin.h" +#endif + +#include /* initgroups */ +#include /* getpwuid */ +#include /* setlocale */ +#include + +#define MAXPROCTITLE 2048 /* Maximum amount of proc title we'll use. */ +#undef MIN +#define MIN(a,b) ((a)<(b)?(a):(b)) +#ifndef UID_NOBODY +#define UID_NOBODY 65534 +#endif +#ifndef GID_NOGROUP +#define GID_NOGROUP 65534 +#endif + + + + + +extern int yy_flex_debug; + +static int _dict_daemon; +static int _dict_reaps; + +static char *_dict_argvstart; +static int _dict_argvlen; + + int _dict_forks; + + + +int default_strategy_set; /* 1 if set by command line option */ + + +int logOptions = 0; + +const char *logFile = NULL; +int logFile_set; /* 1 if set by command line option */ + +const char *pidFile = "/var/run/dictd.pid"; +int pidFile_set; /* 1 if set by command line option */ + +const char *daemon_service = DICT_DEFAULT_SERVICE; +int daemon_service_set; /* 1 if set by command line option */ + +int _dict_daemon_limit = DICT_DAEMON_LIMIT; +int _dict_daemon_limit_set; /* 1 if set by command line option */ + +int _dict_markTime = 0; +int _dict_markTime_set; /* 1 if set by command line option */ + +const char *locale = NULL; +int locale_set; /* 1 if set by command line option */ + +int client_delay = DICT_DEFAULT_DELAY; +int client_delay_set; /* 1 if set by command line option */ + +int depth = DICT_QUEUE_DEPTH; +int depth_set; /* 1 if set by command line option */ + +int useSyslog = 0; +int syslog_facility_set; /* 1 if set by command line option */ + +const char *preprocessor = NULL; + +const char *bind_to = NULL; +int bind_to_set; /* 1 if set by command line option */ + + + + + + +int inetd = 0; + +int need_reload_config = 0; + +int need_unload_databases = 0; +int databases_unloaded = 0; + +static const char *configFile = DICT_CONFIG_PATH DICTD_CONFIG_NAME; + +static void dict_close_databases (dictConfig *c); +static void sanity (const char *confFile); +static void dict_init_databases (dictConfig *c); +static void dict_config_print (FILE *stream, dictConfig *c); +static void postprocess_filenames (dictConfig *dc); + +void dict_initsetproctitle( int argc, char **argv, char **envp ) +{ + int i; + + _dict_argvstart = argv[0]; + + for (i = 0; envp[i]; i++) continue; + + if (i) + _dict_argvlen = envp[i-1] + strlen(envp[i-1]) - _dict_argvstart; + else + _dict_argvlen = argv[argc-1] + strlen(argv[argc-1]) - _dict_argvstart; + + argv[1] = NULL; +} + +void dict_setproctitle( const char *format, ... ) +{ + va_list ap; + int len; + char buf[MAXPROCTITLE]; + + va_start( ap, format ); + vsnprintf( buf, MAXPROCTITLE, format, ap ); + va_end( ap ); + + if ((len = strlen(buf)) > MAXPROCTITLE-1) + err_fatal( __FUNCTION__, "buffer overflow (%d)\n", len ); + + buf[ MIN(_dict_argvlen,MAXPROCTITLE) - 1 ] = '\0'; + strcpy( _dict_argvstart, buf ); + memset( _dict_argvstart+len, 0, _dict_argvlen-len ); +} + +const char *dict_format_time( double t ) +{ + static int current = 0; + static char buf[10][128]; /* Rotate 10 buffers */ + static char *this; + long int s, m, h, d; + + this = buf[current]; + if (++current >= 10) current = 0; + + if (t < 600) { + snprintf( this, sizeof (buf [0]), "%0.3f", t ); + } else { + s = (long int)t; + d = s / (3600*24); + s -= d * 3600 * 24; + h = s / 3600; + s -= h * 3600; + m = s / 60; + s -= m * 60; + + if (d) + snprintf( this, sizeof (buf [0]), "%ld+%02ld:%02ld:%02ld", d, h, m, s ); + else if (h) + snprintf( this, sizeof (buf [0]), "%02ld:%02ld:%02ld", h, m, s ); + else + snprintf( this, sizeof (buf [0]), "%02ld:%02ld", m, s ); + } + + return this; +} + +static int waitpid__exit_status (int status) +{ + if (WIFEXITED(status)){ + return WEXITSTATUS(status); + }else if (WIFSIGNALED(status)){ + return 128 + WTERMSIG(status); + }else{ + return -1; + } +} + +static void reaper( int dummy ) +{ +#if 0 + union wait status; +#else + int status; +#endif + pid_t pid; + + while ((pid = wait3(&status, WNOHANG, NULL)) > 0) { + ++_dict_reaps; + + if (flg_test(LOG_SERVER)) + log_info( ":I: Reaped %d%s, exit status %i\n", + pid, + _dict_daemon ? " IN CHILD": "", + waitpid__exit_status (status)); + } +} + +static int start_daemon( void ) +{ + pid_t pid; + + ++_dict_forks; + switch ((pid = fork())) { + case 0: + ++_dict_daemon; + break; + case -1: + log_info( ":E: Unable to fork daemon\n" ); + alarm(10); /* Can't use sleep() here */ + pause(); + break; + default: + if (flg_test(LOG_SERVER)) log_info( ":I: Forked %d\n", pid ); + break; + } + return pid; +} + +static const char * signal2name (int sig) +{ + static char name [50]; + + switch (sig) { + case SIGHUP: + return "SIGHUP"; + case SIGINT: + return "SIGINT"; + case SIGQUIT: + return "SIGQUIT"; + case SIGILL: + return "SIGILL"; + case SIGTRAP: + return "SIGTRAP"; + case SIGTERM: + return "SIGTERM"; + case SIGPIPE: + return "SIGPIPE"; + case SIGALRM: + return "SIGALRM"; + default: + snprintf (name, sizeof (name), "Signal %d", sig); + return name; + } +} + +static void log_sig_info (int sig) +{ + log_info ( + ":I: %s: c/f = %d/%d; %sr %su %ss\n", + signal2name (sig), + _dict_comparisons, + _dict_forks, + dict_format_time (tim_get_real ("dictd")), + dict_format_time (tim_get_user ("dictd")), + dict_format_time (tim_get_system ("dictd"))); +} + +static void unload_databases (void) +{ + dict_close_databases (DictConfig); + DictConfig = NULL; +} + +static void reload_config (void) +{ + dict_close_databases (DictConfig); + + if (!access(configFile,R_OK)){ + prs_file_pp (preprocessor, configFile); + postprocess_filenames (DictConfig); + } + + sanity (configFile); + + if (dbg_test (DBG_VERBOSE)) + dict_config_print( NULL, DictConfig ); + + dict_init_databases (DictConfig); +} + +static void handler( int sig ) +{ + const char *name = NULL; + time_t t; + + name = signal2name (sig); + + if (_dict_daemon) { + daemon_terminate( sig, name ); + } else { + tim_stop( "dictd" ); + switch (sig){ + case SIGALRM: + if (_dict_markTime > 0){ + time(&t); + log_info( ":T: %24.24s; %d/%d %sr %su %ss\n", + ctime(&t), + _dict_forks - _dict_reaps, + _dict_forks, + dict_format_time( tim_get_real( "dictd" ) ), + dict_format_time( tim_get_user( "dictd" ) ), + dict_format_time( tim_get_system( "dictd" ) ) ); + alarm(_dict_markTime); + return; + } + + break; + } + + log_sig_info (sig); + } + if (!dbg_test(DBG_NOFORK) || sig != SIGALRM) + exit(sig+128); +} + +static const char *postprocess_filename (const char *fn, const char *prefix) +{ + char *new_fn; + + if (!fn) + return NULL; + + if (fn [0] != '/' && fn [0] != '.'){ + new_fn = xmalloc (2 + strlen (prefix) + strlen (fn)); + strcpy (new_fn, prefix); + strcat (new_fn, fn); + + return new_fn; + }else{ + return xstrdup (fn); + } +} + +const char *postprocess_plugin_filename (const char *fn) +{ + return postprocess_filename (fn, DICT_PLUGIN_PATH); +} + +const char *postprocess_dict_filename (const char *fn) +{ + return postprocess_filename (fn, DICT_DICTIONARY_PATH); +} + +static void postprocess_filenames (dictConfig *dc) +{ + lst_Position p; + dictDatabase *db; + + LST_ITERATE(dc -> dbl, p, db) { + db -> dataFilename = postprocess_dict_filename (db -> dataFilename); + db -> indexFilename = postprocess_dict_filename (db -> indexFilename); + db -> indexsuffixFilename = postprocess_dict_filename (db -> indexsuffixFilename); + db -> indexwordFilename = postprocess_dict_filename (db -> indexwordFilename); + db -> pluginFilename = postprocess_plugin_filename (db -> pluginFilename); + } + + dc -> site = postprocess_dict_filename (dc -> site); +} + +static void handler_sighup (int sig) +{ + log_sig_info (sig); + need_reload_config = 1; +} + +static void handler_sigusr1 (int sig) +{ + log_sig_info (sig); + need_unload_databases = 1; +} + +static void setsig( int sig, void (*f)(int), int sa_flags ) +{ + struct sigaction sa; + + sa.sa_handler = f; + sigemptyset(&sa.sa_mask); + sa.sa_flags = sa_flags; + sigaction(sig, &sa, NULL); +} + +struct access_print_struct { + FILE *s; + int offset; +}; + +static int access_print( const void *datum, void *arg ) +{ + dictAccess *a = (dictAccess *)datum; + struct access_print_struct *aps = (struct access_print_struct *)arg; + FILE *s = aps->s; + int offset = aps->offset; + int i; + const char *desc; + + for (i = 0; i < offset; i++) fputc( ' ', s ); + switch (a->type) { + case DICT_DENY: desc = "deny"; break; + case DICT_ALLOW: desc = "allow"; break; + case DICT_AUTHONLY: desc = "authonly"; break; + case DICT_USER: desc = "user"; break; + case DICT_GROUP: desc = "group"; break; /* Not implemented. */ + default: desc = "unknown"; break; + } + fprintf( s, "%s %s\n", desc, a->spec ); + return 0; +} + +static void acl_print( FILE *s, lst_List l, int offset) +{ + struct access_print_struct aps; + int i; + + aps.s = s; + aps.offset = offset + 3; + + for (i = 0; i < offset; i++) fputc( ' ', s ); + fprintf( s, "access {\n" ); + lst_iterate_arg( l, access_print, &aps ); + for (i = 0; i < offset; i++) fputc( ' ', s ); + fprintf( s, "}\n" ); +} + +static int user_print( const void *key, const void *datum, void *arg ) +{ + const char *username = (const char *)key; + const char *secret = (const char *)datum; + FILE *s = (FILE *)arg; + + if (dbg_test(DBG_AUTH)) + fprintf( s, "user %s %s\n", username, secret ); + else + fprintf( s, "user %s *\n", username ); + return 0; +} + +static int config_print( const void *datum, void *arg ) +{ + dictDatabase *db = (dictDatabase *)datum; + FILE *s = (FILE *)arg; + + fprintf( s, "database %s {\n", db->databaseName ); + + if (db->dataFilename) + fprintf( s, " data %s\n", db->dataFilename ); + if (db->indexFilename) + fprintf( s, " index %s\n", db->indexFilename ); + if (db->indexsuffixFilename) + fprintf( s, " index_suffix %s\n", db->indexsuffixFilename ); + if (db->indexwordFilename) + fprintf( s, " index_word %s\n", db->indexwordFilename ); + if (db->filter) + fprintf( s, " filter %s\n", db->filter ); + if (db->prefilter) + fprintf( s, " prefilter %s\n", db->prefilter ); + if (db->postfilter) + fprintf( s, " postfilter %s\n", db->postfilter ); + if (db->databaseShort) + fprintf( s, " name %s\n", db->databaseShort ); + if (db->acl) + acl_print( s, db->acl, 3 ); + + fprintf( s, "}\n" ); + + return 0; +} + +static void dict_config_print( FILE *stream, dictConfig *c ) +{ + FILE *s = stream ? stream : stderr; + + if (c->acl) acl_print( s, c->acl, 0 ); + lst_iterate_arg( c->dbl, config_print, s ); + if (c->usl) hsh_iterate_arg( c->usl, user_print, s ); +} + +static const char *get_entry_info( dictDatabase *db, const char *entryName ) +{ + dictWord *dw; + lst_List list = lst_create(); + char *pt, *buf; + + if ( + 0 >= dict_search ( + list, entryName, db, DICT_STRAT_EXACT, 0, + NULL, NULL, NULL )) + { +#ifdef USE_PLUGIN + call_dictdb_free (DictConfig->dbl); +#endif + lst_destroy( list ); + return NULL; + } + + dw = lst_nth_get( list, 1 ); + + assert (dw -> database); + + buf = pt = dict_data_obtain( dw -> database, dw ); + + if (!strncmp (pt, "00database", 10) || !strncmp (pt, "00-database", 11)){ + while (*pt != '\n') + ++pt; + + ++pt; + } + + while (*pt == ' ' || *pt == '\t') + ++pt; + + pt[ strlen(pt) - 1 ] = '\0'; + +#ifdef USE_PLUGIN + call_dictdb_free (DictConfig->dbl); +#endif + dict_destroy_list( list ); + + pt = xstrdup (pt); + + xfree (buf); + + return pt; +} + +static dictDatabase *dbname2database (const char *dbname) +{ + dictDatabase *db = NULL; + lst_Position db_pos = lst_init_position (DictConfig->dbl); + + while (db_pos){ + db = lst_get_position (db_pos); + + if (!strcmp (db -> databaseName, dbname)){ + return db; + } + + db_pos = lst_next_position (db_pos); + } + + return NULL; +} + +static lst_List string2virtual_db_list (char *s) +{ + int len, i; + lst_List virtual_db_list; + char *p; + + dictDatabase *db = NULL; + + p = s; + len = strlen (s); + + virtual_db_list = lst_create (); + + for (i = 0; i <= len; ++i){ + if (s [i] == ',' || s [i] == '\n' || s [i] == '\0'){ + s [i] = '\0'; + + if (*p){ + db = dbname2database (p); + + if (db){ + lst_append (virtual_db_list, db); + }else{ + log_info( ":E: Unknown database '%s'\n", p ); + PRINTF(DBG_INIT, (":E: Unknown database '%s'\n", p)); + exit (2); + } + } + + p = s + i + 1; + } + } + + return virtual_db_list; +} + +static int init_virtual_db_list (const void *datum) +{ + lst_List list; + dictDatabase *db = (dictDatabase *)datum; + dictWord *dw; + char *buf; + int ret; + + if (db -> database_list){ + buf = xstrdup (db -> database_list); + db -> virtual_db_list = string2virtual_db_list (buf); + xfree (buf); + }else{ + if (!db -> index) + return 0; + + list = lst_create(); + ret = dict_search ( + list, DICT_FLAG_VIRTUAL, db, DICT_STRAT_EXACT, 0, + NULL, NULL, NULL); + + switch (ret){ + case 1: case 2: + dw = (dictWord *) lst_pop (list); + buf = dict_data_obtain (db, dw); + dict_destroy_datum (dw); + + db -> virtual_db_list = string2virtual_db_list (buf); + + xfree (buf); + break; + case 0: + break; + default: + err_fatal ( + __FUNCTION__, + "index file contains more than one %s entry", + DICT_FLAG_VIRTUAL); + } + + dict_destroy_list (list); + } + + return 0; +} + +static int init_mime_db_list (const void *datum) +{ + lst_List list; + dictDatabase *db = (dictDatabase *)datum; + dictWord *dw; + char *buf; + int ret; + + if (!db -> mime_db) + return 0; + + /* MIME */ + if (db -> mime_mimeDbname){ + db -> mime_mimeDB = dbname2database (db -> mime_mimeDbname); + + if (!db -> mime_mimeDB){ + err_fatal ( + __FUNCTION__, + "Incorrect database name '%s'\n", + db -> mime_mimeDbname); + } + }else{ + err_fatal ( + __FUNCTION__, + "MIME database '%s' has no mime_dbname keyword\n", + db -> databaseName); + } + + /* NO MIME */ + if (db -> mime_nomimeDbname){ + db -> mime_nomimeDB = dbname2database (db -> mime_nomimeDbname); + + if (!db -> mime_nomimeDB){ + err_fatal ( + __FUNCTION__, + "Incorrect database name '%s'\n", + db -> mime_nomimeDbname); + } + }else{ + err_fatal ( + __FUNCTION__, + "MIME database '%s' has no nomime_dbname keyword\n", + db -> databaseName); + } + + return 0; +} + +static int init_plugin( const void *datum ) +{ +#ifdef USE_PLUGIN + dictDatabase *db = (dictDatabase *)datum; + dict_plugin_init (db); +#endif + + return 0; +} + +void dict_disable_strat (dictDatabase *db, const char* strategy) +{ + int strat = -1; + int array_size = get_max_strategy_num () + 1; + + assert (db); + assert (strategy); + + if (!db -> strategy_disabled){ + db -> strategy_disabled = xmalloc (array_size * sizeof (int)); + memset (db -> strategy_disabled, 0, array_size * sizeof (int)); + } + + strat = lookup_strategy_ex (strategy); + assert (strat >= 0); + + db -> strategy_disabled [strat] = 1; +} + +static void init_database_alphabet (dictDatabase *db) +{ + int ret; + lst_List l; + const dictWord *dw; + char *data; + + if (!db -> normal_db) + return; + + l = lst_create (); + + ret = dict_search_database_ (l, DICT_FLAG_ALPHABET, db, DICT_STRAT_EXACT); + + if (ret){ + dw = (const dictWord *) lst_top (l); + data = dict_data_obtain (db, dw); + db -> alphabet = data; + + data = strchr (db -> alphabet, '\n'); + if (data) + *data = 0; + } + + dict_destroy_list (l); +} + +static void init_database_default_strategy (dictDatabase *db) +{ + int ret; + lst_List l; + const dictWord *dw; + char *data; + int def_strat = -1; + char *p; + + if (!db -> normal_db) + return; + + if (db -> default_strategy > 0){ + /* already set by `default_strategy' directive*/ + return; + } + + l = lst_create (); + + ret = dict_search_database_ (l, DICT_FLAG_DEFAULT_STRAT, db, DICT_STRAT_EXACT); + + if (ret){ + dw = (const dictWord *) lst_top (l); + data = dict_data_obtain (db, dw); + + for (p=data; *p && isalpha ((unsigned char) *p); ++p){ + } + *p = '\0'; + + def_strat = lookup_strategy (data); + if (-1 == def_strat){ + PRINTF (DBG_INIT, (":I: `%s' is not supported by dictd\n", data)); + }else{ + db -> default_strategy = def_strat; + } + + xfree (data); + } + + dict_destroy_list (l); +} + +static int init_database_mime_header (const void *datum) +{ + dictDatabase *db = (dictDatabase *) datum; + int ret; + lst_List l; + const dictWord *dw; + char *data; + + if (!db -> normal_db) + return 0; + + if (db -> mime_header){ + /* already set by `mime_header' directive*/ + return 0; + } + + l = lst_create (); + + ret = dict_search_database_ (l, DICT_FLAG_MIME_HEADER, db, DICT_STRAT_EXACT); + + if (ret){ + dw = (const dictWord *) lst_top (l); + data = dict_data_obtain (db, dw); + + db -> mime_header = xstrdup (data); + + xfree (data); + } + + dict_destroy_list (l); + + return 0; +} + +static int init_database( const void *datum ) +{ + dictDatabase *db = (dictDatabase *)datum; + const char *strat_name = NULL; + + PRINTF (DBG_INIT, (":I: Initializing '%s'\n", db->databaseName)); + + if (db->indexFilename){ + PRINTF (DBG_INIT, (":I: Opening indices\n")); + } + + db->index = dict_index_open( db->indexFilename, 1, 0, 0 ); + + if (db->indexFilename){ + PRINTF (DBG_INIT, (":I: .index \n")); + } + + if (db->index){ + db->index_suffix = dict_index_open( + db->indexsuffixFilename, + 0, db->index->flag_utf8, db->index->flag_allchars); + db->index_word = dict_index_open( + db->indexwordFilename, + 0, db->index->flag_utf8, db->index->flag_allchars); + } + + if (db->index_suffix){ + PRINTF (DBG_INIT, (":I: .indexsuffix \n")); + db->index_suffix->flag_8bit = db->index->flag_8bit; + db->index_suffix->flag_utf8 = db->index->flag_utf8; + db->index_suffix->flag_allchars = db->index->flag_allchars; + } + if (db->index_word){ + PRINTF (DBG_INIT, (":I: .indexword \n")); + db->index_word->flag_utf8 = db->index->flag_utf8; + db->index_word->flag_8bit = db->index->flag_8bit; + db->index_word->flag_allchars = db->index->flag_allchars; + } + + if (db->dataFilename){ + PRINTF (DBG_INIT, (":I: Opening data\n")); + } + + db->data = dict_data_open( db->dataFilename, 0 ); + + init_database_alphabet (db); + if (db -> alphabet){ + PRINTF (DBG_INIT, (":I: alphabet: %s\n", db -> alphabet)); + }else{ + PRINTF (DBG_INIT, (":I: alphabet: (NULL)\n")); + } + + if (db -> default_strategy){ + strat_name = get_strategy (db -> default_strategy) -> name; + PRINTF (DBG_INIT, (":I: default_strategy (from conf file): %s\n", + strat_name)); + }else{ + init_database_default_strategy (db); + if (db -> default_strategy){ + strat_name = get_strategy (db -> default_strategy) -> name; + PRINTF (DBG_INIT, (":I: default_strategy (from db): %s\n", strat_name)); + }else{ + db -> default_strategy = default_strategy; + } + } + + if (db->dataFilename){ + PRINTF(DBG_INIT, + (":I: '%s' initialized\n", db->databaseName)); + } + + return 0; +} + +static int init_database_short (const void *datum) +{ + char *NL; + + dictDatabase *db = (dictDatabase *) datum; + + if (!db->databaseShort){ + db->databaseShort = get_entry_info( db, DICT_SHORT_ENTRY_NAME ); + }else if (*db->databaseShort == '@'){ + db->databaseShort = get_entry_info( db, db->databaseShort + 1 ); + }else{ + db->databaseShort = xstrdup (db->databaseShort); + } + + if (db->databaseShort){ + NL = strchr (db->databaseShort, '\n'); + if (NL) + *NL = 0; + } + + if (!db->databaseShort) + db->databaseShort = xstrdup (db->databaseName); + + return 0; +} + +static int close_plugin (const void *datum) +{ +#ifdef USE_PLUGIN + dictDatabase *db = (dictDatabase *)datum; + dict_plugin_destroy (db); +#endif + + return 0; +} + +static int close_database (const void *datum) +{ + dictDatabase *db = (dictDatabase *)datum; + + dict_index_close (db->index); + dict_index_close (db->index_suffix); + dict_index_close (db->index_word); + + dict_data_close (db->data); + + if (db -> databaseShort) + xfree ((void *) db -> databaseShort); + + if (db -> indexFilename) + xfree ((void *) db -> indexFilename); + if (db -> dataFilename) + xfree ((void *) db -> dataFilename); + if (db -> indexwordFilename) + xfree ((void *) db -> indexwordFilename); + if (db -> indexsuffixFilename) + xfree ((void *) db -> indexsuffixFilename); + if (db -> pluginFilename) + xfree ((void *) db -> pluginFilename); + if (db -> strategy_disabled) + xfree ((void *) db -> strategy_disabled); + if (db -> alphabet) + xfree ((void *) db -> alphabet); + if (db -> mime_header) + xfree ((void *) db -> mime_header); + + return 0; +} + +static int log_database_info( const void *datum ) +{ + dictDatabase *db = (dictDatabase *)datum; + const char *pt; + unsigned long headwords = 0; + + if (db->index){ + for (pt = db->index->start; pt < db->index->end; pt++) + if (*pt == '\n') ++headwords; + db->index->headwords = headwords; + + log_info( ":I: %-12.12s %12lu %12lu %12lu %12lu\n", + db->databaseName, headwords, + db->index->size, db->data->size, db->data->length ); + } + + return 0; +} + +static void dict_ltdl_init () +{ +#if USE_PLUGIN && !HAVE_DLFCN_H + if (lt_dlinit ()) + err_fatal( __FUNCTION__, "Can not initialize 'ltdl' library\n" ); +#endif +} + +static void dict_ltdl_close () +{ +#if USE_PLUGIN && !HAVE_DLFCN_H + if (lt_dlexit ()) + err_fatal( __FUNCTION__, "Can not deinitialize 'ltdl' library\n" ); +#endif +} + +/* + Makes dictionary_exit db invisible if it is the last visible one + */ +static void make_dictexit_invisible (dictConfig *c) +{ + lst_Position p; + dictDatabase *db; + dictDatabase *db_exit = NULL; + + LST_ITERATE(c -> dbl, p, db) { + if (!db -> invisible){ + if (db_exit) + db_exit -> invisible = 0; + + db_exit = NULL; + } + + if (db -> exit_db){ + db_exit = db; + db_exit -> invisible = 1; + } + } +} + +static void dict_init_databases( dictConfig *c ) +{ + make_dictexit_invisible (c); + + lst_iterate( c->dbl, init_database ); + lst_iterate( c->dbl, init_plugin ); + lst_iterate( c->dbl, init_virtual_db_list ); + lst_iterate( c->dbl, init_mime_db_list ); + lst_iterate( c->dbl, init_database_short ); + lst_iterate( c->dbl, init_database_mime_header); + lst_iterate( c->dbl, log_database_info ); +} + +static void dict_close_databases (dictConfig *c) +{ + dictDatabase *db; + dictAccess *acl; + + if (!c) + return; + + if (c -> dbl){ + while (lst_length (c -> dbl) > 0){ + db = (dictDatabase *) lst_pop (c -> dbl); + + if (db -> virtual_db_list) + lst_destroy (db -> virtual_db_list); + + close_plugin (db); + close_database (db); + xfree (db); + } + lst_destroy (c -> dbl); + } + + if (c -> acl){ + while (lst_length (c -> acl) > 0){ + acl = (dictAccess *) lst_pop (c->acl); + xfree (acl); + } + lst_destroy (c -> acl); + } + + if (c -> site) + xfree ((void *) c -> site); + + xfree (c); +} + +static int match_mode = 0; + +static int dump_def( const void *datum ) +{ + char *buf; + const dictWord *dw = (dictWord *)datum; + + const dictDatabase *db = dw -> database_visible; + if (!db) + db = dw -> database; + + if (match_mode){ + printf ( + "%s:\t\"%s\"\n", db -> databaseName, dw -> word ); + }else{ + buf = dict_data_obtain( dw -> database, dw ); + + printf ( + "From %s [%s]:\n\n%s\n", db -> databaseShort, db -> databaseName, buf ); + + xfree( buf ); + } + + return 0; +} + +static void dict_dump_defs( lst_List list ) +{ + lst_iterate (list, dump_def); +} + +static const char *id_string( const char *id ) +{ + static char buffer [BUFFERSIZE]; + + snprintf( buffer, BUFFERSIZE, "%s", DICT_VERSION ); + + return buffer; +} + +const char *dict_get_banner( int shortFlag ) +{ + static char *shortBuffer = NULL; + static char *longBuffer = NULL; + const char *id = "$Id: dictd.c,v 1.124 2005/04/14 07:52:16 cheusov Exp $"; + struct utsname uts; + + if (shortFlag && shortBuffer) return shortBuffer; + if (!shortFlag && longBuffer) return longBuffer; + + uname( &uts ); + + shortBuffer = xmalloc(256); + snprintf( + shortBuffer, 256, + "%s %s", err_program_name(), id_string( id ) ); + + longBuffer = xmalloc(256); + snprintf( + longBuffer, 256, + "%s %s/rf on %s %s", err_program_name(), id_string( id ), + uts.sysname, + uts.release ); + + if (shortFlag) + return shortBuffer; + + return longBuffer; +} + +static void banner( void ) +{ + printf( "%s\n", dict_get_banner(0) ); + printf( "Copyright 1997-2002 Rickard E. Faith (faith@dict.org)\n\n" ); +} + +static void license( void ) +{ + static const char *license_msg[] = { + "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 1, 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.,", + "675 Mass Ave, Cambridge, MA 02139, USA.", + 0 }; + const char **p = license_msg; + + banner(); + while (*p) printf( " %s\n", *p++ ); +} + +static void help( void ) +{ + static const char *help_msg[] = { + "Usage: dictd [options]", + "Start the dictd daemon", + "", + "-h --help give this help", + " --license display software license", + "-v --verbose verbose mode", + "-V --version display version number", + "-p --port port number", + " --delay client timeout in seconds", + " --depth TCP/IP queue depth", + " --limit maximum simultaneous children", + "-c --config configuration file", + "-l --log