[Debian-l10n-commits] r1394 - in /virtaal: ./ branches/ branches/upstream/ branches/upstream/current/ branches/upstream/current/bin/ branches/upstream/current/po/ branches/upstream/current/share/ branches/upstream/current/share/applications/ branches/upstream/current/share/icons/ branches/upstream/current/share/mime/ branches/upstream/current/share/mime/packages/ branches/upstream/current/share/virtaal/ branches/upstream/current/share/virtaal/autocorr/ branches/upstream/current/virtaal/ branches/upstream/current/virtaal/support/ branches/upstream/current/virtaal/widgets/
nekral-guest at users.alioth.debian.org
nekral-guest at users.alioth.debian.org
Fri Oct 3 19:42:05 UTC 2008
Author: nekral-guest
Date: Fri Oct 3 19:42:03 2008
New Revision: 1394
URL: http://svn.debian.org/wsvn/?sc=1&rev=1394
Log:
[svn-inject] Installing original source of virtaal
Added:
virtaal/
virtaal/branches/
virtaal/branches/upstream/
virtaal/branches/upstream/current/
virtaal/branches/upstream/current/LICENSE
virtaal/branches/upstream/current/PKG-INFO
virtaal/branches/upstream/current/README
virtaal/branches/upstream/current/bin/
virtaal/branches/upstream/current/bin/virtaal (with props)
virtaal/branches/upstream/current/maketranslations (with props)
virtaal/branches/upstream/current/po/
virtaal/branches/upstream/current/po/.intltool-merge-cache
virtaal/branches/upstream/current/po/Makevars
virtaal/branches/upstream/current/po/POTFILES.in
virtaal/branches/upstream/current/po/README
virtaal/branches/upstream/current/po/af.po
virtaal/branches/upstream/current/po/gtk20-lite.pot
virtaal/branches/upstream/current/po/intltool-update (with props)
virtaal/branches/upstream/current/po/testlocalisations (with props)
virtaal/branches/upstream/current/po/virtaal.pot
virtaal/branches/upstream/current/setup.py (with props)
virtaal/branches/upstream/current/share/
virtaal/branches/upstream/current/share/applications/
virtaal/branches/upstream/current/share/applications/virtaal.desktop
virtaal/branches/upstream/current/share/icons/
virtaal/branches/upstream/current/share/icons/virtaal.ico (with props)
virtaal/branches/upstream/current/share/icons/virtaal.png (with props)
virtaal/branches/upstream/current/share/mime/
virtaal/branches/upstream/current/share/mime/packages/
virtaal/branches/upstream/current/share/mime/packages/virtaal-mimetype.xml
virtaal/branches/upstream/current/share/virtaal/
virtaal/branches/upstream/current/share/virtaal/autocorr/
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_af-ZA.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_bg-BG.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_cs-CZ.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_da-DK.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_de-DE.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_en-GB.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_en-US.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_en-ZA.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_es-ES.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_fi-FI.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_fr-FR.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_hu-HU.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_it-IT.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_ja-JP.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_ko-KR.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_nl-NL.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_pl-PL.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_pt-BR.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_pt-PT.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_ru-RU.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_sk-SK.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_sl-SI.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_sv-SE.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_tr-TR.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_vi-VN.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_zh-CN.dat (with props)
virtaal/branches/upstream/current/share/virtaal/autocorr/acor_zh-TW.dat (with props)
virtaal/branches/upstream/current/share/virtaal/virtaal.glade
virtaal/branches/upstream/current/share/virtaal/virtaal_logo.png (with props)
virtaal/branches/upstream/current/share/virtaal/virtaal_logo.svg
virtaal/branches/upstream/current/virtaal/
virtaal/branches/upstream/current/virtaal/__init__.py
virtaal/branches/upstream/current/virtaal/__version__.py
virtaal/branches/upstream/current/virtaal/about.py
virtaal/branches/upstream/current/virtaal/autocompletor.py
virtaal/branches/upstream/current/virtaal/autocorrector.py
virtaal/branches/upstream/current/virtaal/document.py
virtaal/branches/upstream/current/virtaal/formats.py
virtaal/branches/upstream/current/virtaal/main_window.py
virtaal/branches/upstream/current/virtaal/markup.py
virtaal/branches/upstream/current/virtaal/mode_selector.py
virtaal/branches/upstream/current/virtaal/modes.py
virtaal/branches/upstream/current/virtaal/pan_app.py
virtaal/branches/upstream/current/virtaal/recent.py
virtaal/branches/upstream/current/virtaal/rendering.py
virtaal/branches/upstream/current/virtaal/search_mode.py
virtaal/branches/upstream/current/virtaal/store_grid.py
virtaal/branches/upstream/current/virtaal/store_model.py
virtaal/branches/upstream/current/virtaal/support/
virtaal/branches/upstream/current/virtaal/support/__init__.py
virtaal/branches/upstream/current/virtaal/support/bijection.py
virtaal/branches/upstream/current/virtaal/support/memoize.py
virtaal/branches/upstream/current/virtaal/support/openmailto.py
virtaal/branches/upstream/current/virtaal/support/partial.py
virtaal/branches/upstream/current/virtaal/support/set_enumerator.py
virtaal/branches/upstream/current/virtaal/support/simplegeneric.py
virtaal/branches/upstream/current/virtaal/support/sorted_set.py
virtaal/branches/upstream/current/virtaal/terminology.py
virtaal/branches/upstream/current/virtaal/tips.py
virtaal/branches/upstream/current/virtaal/undo_buffer.py
virtaal/branches/upstream/current/virtaal/unit_editor.py
virtaal/branches/upstream/current/virtaal/unit_layout.py
virtaal/branches/upstream/current/virtaal/unit_renderer.py
virtaal/branches/upstream/current/virtaal/widgets/
virtaal/branches/upstream/current/virtaal/widgets/__init__.py
virtaal/branches/upstream/current/virtaal/widgets/entry_dialog.py
virtaal/branches/upstream/current/virtaal/widgets/label_expander.py
virtaal/branches/upstream/current/virtaal/widgets/util.py
Added: virtaal/branches/upstream/current/LICENSE
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/LICENSE?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/LICENSE (added)
+++ virtaal/branches/upstream/current/LICENSE Fri Oct 3 19:42:03 2008
@@ -1,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Added: virtaal/branches/upstream/current/PKG-INFO
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/PKG-INFO?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/PKG-INFO (added)
+++ virtaal/branches/upstream/current/PKG-INFO Fri Oct 3 19:42:03 2008
@@ -1,0 +1,25 @@
+Metadata-Version: 1.0
+Name: virtaal
+Version: 0.2-rc1
+Summary: A tool to create program translations.
+Home-page: http://translate.sourceforge.net/wiki/virtaal/index
+Author: Translate.org.za
+Author-email: translate-devel at lists.sourceforge.net
+License: GNU General Public License (GPL)
+Download-URL: http://sourceforge.net/project/showfiles.php?group_id=91920&package_id=270877
+Description: Virtaal is used to create program translations.
+
+ It uses the Translate Toolkit to get access to translation files and therefore
+ can edit a variety of files (including PO and XLIFF files).
+Platform: any
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Console
+Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: End Users/Desktop
+Classifier: Intended Audience :: Information Technology
+Classifier: License :: OSI Approved :: GNU General Public License (GPL)
+Classifier: Programming Language :: Python
+Classifier: Topic :: Software Development :: Localization
+Classifier: Topic :: Text Processing :: LinguisticOperating System :: OS Independent
+Classifier: Operating System :: Microsoft :: Windows
+Classifier: Operating System :: Unix
Added: virtaal/branches/upstream/current/README
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/README?rev=1394&op=file
==============================================================================
(empty)
Added: virtaal/branches/upstream/current/bin/virtaal
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/bin/virtaal?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/bin/virtaal (added)
+++ virtaal/branches/upstream/current/bin/virtaal Fri Oct 3 19:42:03 2008
@@ -1,0 +1,131 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2007-2008 Zuza Software Foundation
+#
+# This file is part of Virtaal
+#
+# translate 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.
+#
+# translate 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 translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+import sys
+import logging
+from optparse import OptionParser, make_option, OptionValueError
+from os import path
+
+from translate.storage import factory
+
+from virtaal.main_window import Virtaal
+from virtaal import pan_app
+from virtaal import __version__
+from virtaal import terminology
+
+def set_termininology_dir(option, opt_str, value, parser):
+ def get_term(value):
+ if not path.isdir(value):
+ try:
+ return factory.getobject(value)
+ except ValueError:
+ raise OptionValueError(_("You must specify a directory or a translation store file for --terminology"))
+ return value
+ parser.values.terminology = get_term(value)
+
+usage = _("%prog [options] [translation_file]")
+option_list = [
+ make_option("--profile",
+ action="store", type="string", dest="profile", metavar=_("PROFILE"),
+ help=_("Perform profiling, storing the result to the supplied filename.")),
+ make_option("--log",
+ action="store", type="string", dest="log", metavar=_("LOG"),
+ help=_("Turn on logging, storing the result to the supplied filename.")),
+ make_option("--config",
+ action="store", type="string", dest="config", metavar=_("CONFIG"),
+ help=_("Use the configuration file given by the supplied filename.")),
+ make_option("--terminology", metavar=_("TERMINOLOGY"),
+ action="callback", type="string",
+ callback=set_termininology_dir, nargs=1,
+ help=_("Specify a directory containing terminology files"))
+]
+parser = OptionParser(option_list=option_list, usage=usage, version=__version__.ver)
+
+def main(argv):
+ def set_logging(options):
+ if options.log != None:
+ if options.log.upper() in ('-', 'STDOUT'):
+ logging.basicConfig(level=logging.DEBUG,
+ format='%(asctime)s %(levelname)s %(message)s',
+ stream=sys.stdout)
+ else:
+ try:
+ logging.basicConfig(level=logging.DEBUG,
+ format='%(asctime)s %(levelname)s %(message)s',
+ filename=path.abspath(options.log),
+ filemode='w')
+ except IOError:
+ parser.error(_("Could not open log file '%(filename)s'") % {"filename": options.log})
+
+ def set_config(options):
+ try:
+ if options.config != None:
+ pan_app.settings = pan_app.Settings(path.abspath(options.config))
+ except:
+ parser.error(_("Could not read configuration file '%(filename)s'") % {"filename": options.config})
+
+ def get_startup_file(options):
+ if len(args) > 1:
+ parser.error(_("invalid number of arguments"))
+ elif len(args) == 1:
+ return args[0]
+ else:
+ return None
+
+ def get_virtaal_runner(options):
+ def run_virtaal(startup_file):
+ prog = Virtaal(startup_file)
+ prog.run()
+
+ def profile_runner(startup_file):
+ def profile(profile_file, startup_file):
+ import cProfile
+ import source_tree_infrastructure.lsprofcalltree as lsprofcalltree
+ logging.info('Staring profiling run')
+ profiler = cProfile.Profile()
+ profiler.runcall(run_virtaal, startup_file)
+ k_cache_grind = lsprofcalltree.KCacheGrind(profiler)
+ k_cache_grind.output(profile_file)
+ profile_file.close()
+
+ try:
+ profile(open(options.profile, 'w+'), startup_file)
+ except IOError:
+ parser.error(_("Could not open profile file '%(filename)s'") % {"filename":options.profile})
+
+ def default_runner(startup_file):
+ run_virtaal(startup_file)
+
+ if options.profile != None:
+ return profile_runner
+ else:
+ return default_runner
+
+ options, args = parser.parse_args(argv[1:])
+ set_config(options)
+ set_logging(options)
+ terminology.set_terminology_source(options.terminology)
+ startup_file = get_startup_file(options)
+ runner = get_virtaal_runner(options)
+ runner(startup_file)
+
+if __name__ == "__main__":
+ main(sys.argv)
Propchange: virtaal/branches/upstream/current/bin/virtaal
------------------------------------------------------------------------------
svn:executable =
Added: virtaal/branches/upstream/current/maketranslations
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/maketranslations?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/maketranslations (added)
+++ virtaal/branches/upstream/current/maketranslations Fri Oct 3 19:42:03 2008
@@ -1,0 +1,25 @@
+#!/bin/bash
+
+# Guess the target application if we aren't supplied one
+if [ $# == 1 ]; then
+ targetapp=$1
+else
+ targetapp=$(basename $(pwd))
+fi
+
+share=share/$targetapp
+desktop=share/applications/$targetapp.desktop
+mimetype=share/mime/packages/$targetapp-mimetype.xml
+
+cache="--cache po/.intltool-merge-cache"
+
+if [ -d po ]; then
+ if [ -f ${mimetype}.in ]; then
+ intltool-merge --xml-style $cache po ${mimetype}.in $mimetype
+ fi
+ if [ -f ${desktop}.in ]; then
+ intltool-merge --desktop-style $cache po ${desktop}.in $desktop
+ fi
+else
+ echo "$0: No translation directory"
+fi
Propchange: virtaal/branches/upstream/current/maketranslations
------------------------------------------------------------------------------
svn:executable =
Added: virtaal/branches/upstream/current/po/.intltool-merge-cache
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/po/.intltool-merge-cache?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/po/.intltool-merge-cache (added)
+++ virtaal/branches/upstream/current/po/.intltool-merge-cache Fri Oct 3 19:42:03 2008
@@ -1,0 +1,1 @@
+af
All Supported FilesAlle gesteunde lêersaf
TMXTMXaf
Choose a translation fileKies 'n vertaallêeraf
Qt Linguist Translation FileQt Linguist-vertaallêeraf
INI FileINI-lêeraf
Report a _BugRaporteer 'n _foutaf
INIINIaf
Java Properties FileJava .properties-lêeraf
_Localization Guide_Lokaliseringsgidsaf
OpenOffice.org Translation FileOpenOffice.org-vertaallêeraf
JavaScript error message fileJavaScript-foutboodskaplêeraf
XLIFFXLIFFaf
TMX Translation MemoryTMX-vertaalgehueaf
LOGSTAAFLÃERaf
Wordfast Translation MemoryWordfast-vertaalgeheueaf
VirTaal - %(current_file)s %(modified_marker)sVirTaal - %(current_file)s %(modified_marker)saf
translator-creditsDwayne Baileyaf
© Copyright 2007-2008 Zuza Software Foundation© Kopiereg 2007-2008 Zuza Sagteware Stigtingaf
VirTaal websiteVirTaal-webwerfaf
Tcl Translation FileTcl-vertaallêeraf
Qt Message FileQt-boodskaplêeraf
TBX GlossaryTBX-termlysaf
_Online Help_Aanlynhulpaf
Please enter your team's informationTik jou span inligting inaf
Resource CompilerResource Compileraf
VirTaalVirTaalaf
A translation tool to help a human translator translate files into other languages'n Vertaal program om 'n vertaaler te help om lêers na ander tale te vertaal.af
InitializationInisialiseringaf
invalid number of argumentsverkeerde aantal argumenteaf
F_uzzy_Wysigaf
Advanced Computer Aided Translation (CAT) tool for localization and translationGevorderde program vir rekenaar gesteunde vertaling vir lokaliseerders en vertalersaf
TermBase eXchangeTermBase eXchangeaf
Translation ToolVertaalprogramaf
C++ RC FileC++ RC-lêeraf
RCRCaf
_Help_Hulpaf
XLIFF Translation FileXLIFF-vertaallêeraf
_File_Lêeraf
CONFIGOPSTELLINGaf
%prog [options] [translation_file]%prog [opsies] [vertaal_lêer]af
All FilesAlle lêersaf
XML Localization Interchange File FormatXML Localization Interchange File Formataf
Translation Memory eXchangeTranslation Memory eXchangeaf
Gettext Translation TemplateGettext-vertaalsjabloonaf
TBXTBXaf
Trados Tag EditorTrados-etiketredigeerderaf
PROFILEPROFIELaf
Please enter your nameTik jou naam inaf
Please enter your e-mail addressTik jou e-posaddress in
Added: virtaal/branches/upstream/current/po/Makevars
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/po/Makevars?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/po/Makevars (added)
+++ virtaal/branches/upstream/current/po/Makevars Fri Oct 3 19:42:03 2008
@@ -1,0 +1,4 @@
+top_builddir = ..
+DOMAIN = virtaal
+MSGID_BUGS_ADDRESS = translate-devel at lists.sourceforge.net
+X-PACKAGENAME = Virtaal
Added: virtaal/branches/upstream/current/po/POTFILES.in
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/po/POTFILES.in?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/po/POTFILES.in (added)
+++ virtaal/branches/upstream/current/po/POTFILES.in Fri Oct 3 19:42:03 2008
@@ -1,0 +1,18 @@
+[encoding: UTF-8]
+bin/virtaal
+share/applications/virtaal.desktop.in
+share/virtaal/virtaal.glade
+share/mime/packages/virtaal-mimetype.xml.in
+virtaal/about.py
+virtaal/document.py
+virtaal/formats.py
+virtaal/main_window.py
+virtaal/modes.py
+virtaal/mode_selector.py
+virtaal/pan_app.py
+virtaal/search_mode.py
+virtaal/store_grid.py
+virtaal/support/set_enumerator.py
+virtaal/tips.py
+virtaal/unit_editor.py
+virtaal/unit_layout.py
Added: virtaal/branches/upstream/current/po/README
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/po/README?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/po/README (added)
+++ virtaal/branches/upstream/current/po/README Fri Oct 3 19:42:03 2008
@@ -1,0 +1,15 @@
+Updating translations
+---------------------
+from po/
+
+./intltool-update --pot
+./intltool-update xy
+
+Generating the .xml and .desktop files
+--------------------------------------
+from package /
+
+./maketranslations
+
+This will use the .po files and .xml.in and
+.desktop.in to create a .xml and .desktop file
Added: virtaal/branches/upstream/current/po/af.po
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/po/af.po?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/po/af.po (added)
+++ virtaal/branches/upstream/current/po/af.po Fri Oct 3 19:42:03 2008
@@ -1,0 +1,327 @@
+# Afrikaans (af) localisation of VirTaal.
+# Copyright (C) 2008 Zuza Software Foundation (Translate.org.za)
+# This file is distributed under the same license as the VirTaal package.
+# Dwayne Bailey <dwayne at translate.org.za>, 2008
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: VirTaal 0.1\n"
+"Report-Msgid-Bugs-To: translate-devel at lists.sourceforge.net\n"
+"POT-Creation-Date: 2008-08-03 13:16+0200\n"
+"PO-Revision-Date: 2008-08-02 16:52+0200\n"
+"Last-Translator: Dwayne Bailey <dwayne at translate.org.za>\n"
+"Language-Team: x at example.com\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: VirTaal 0.1\n"
+
+#: ../run_virtaal.py:40
+msgid ""
+"You must specify a directory or a translation store file for --terminology"
+msgstr ""
+
+#: ../run_virtaal.py:44
+msgid "%prog [options] [translation_file]"
+msgstr "%prog [opsies] [vertaal_lêer]"
+
+#: ../run_virtaal.py:47
+msgid "PROFILE"
+msgstr "PROFIEL"
+
+#: ../run_virtaal.py:48
+msgid "Perform profiling, storing the result to the supplied filename."
+msgstr ""
+
+#: ../run_virtaal.py:50
+msgid "LOG"
+msgstr "STAAFLÃER"
+
+#: ../run_virtaal.py:51
+msgid "Turn on logging, storing the result to the supplied filename."
+msgstr ""
+
+#: ../run_virtaal.py:53
+msgid "CONFIG"
+msgstr "OPSTELLING"
+
+#: ../run_virtaal.py:54
+msgid "Use the configuration file given by the supplied filename."
+msgstr ""
+
+#: ../run_virtaal.py:55
+msgid "TERMINOLOGY"
+msgstr ""
+
+#: ../run_virtaal.py:58
+msgid "Specify a directory containing terminology files"
+msgstr ""
+
+#: ../run_virtaal.py:71
+#, python-format
+msgid "Could not open log file '%(filename)s'"
+msgstr ""
+
+#: ../run_virtaal.py:79
+#, python-format
+msgid "Could not read configuration file '%(filename)s'"
+msgstr ""
+
+#: ../run_virtaal.py:83
+msgid "invalid number of arguments"
+msgstr "verkeerde aantal argumente"
+
+#: ../run_virtaal.py:108
+#, python-format
+msgid "Could not open profile file '%(filename)s'"
+msgstr ""
+
+#: ../share/virtaal/virtaal.desktop.in.h:1
+msgid ""
+"A translation tool to help a human translator translate files into other "
+"languages"
+msgstr ""
+"'n Vertaal program om 'n vertaaler te help om lêers na ander tale te vertaal."
+
+#: ../share/virtaal/virtaal.desktop.in.h:2
+msgid "Translation Tool"
+msgstr "Vertaalprogram"
+
+#: ../share/virtaal/virtaal.desktop.in.h:3 ../share/virtaal/virtaal.glade.h:2
+msgid "VirTaal"
+msgstr "VirTaal"
+
+#: ../share/virtaal/virtaal.glade.h:1
+msgid "Report a _Bug"
+msgstr "Raporteer 'n _fout"
+
+#: ../share/virtaal/virtaal.glade.h:3
+msgid "_File"
+msgstr "_Lêer"
+
+#: ../share/virtaal/virtaal.glade.h:4
+msgid "_Help"
+msgstr "_Hulp"
+
+#: ../share/virtaal/virtaal.glade.h:5
+msgid "_Localization Guide"
+msgstr "_Lokaliseringsgids"
+
+#: ../share/virtaal/virtaal.glade.h:6
+msgid "_Online Help"
+msgstr "_Aanlynhulp"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:1
+msgid "C++ RC File"
+msgstr "C++ RC-lêer"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:2
+msgid "Gettext Translation Template"
+msgstr "Gettext-vertaalsjabloon"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:3
+msgid "INI"
+msgstr "INI"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:4
+msgid "INI File"
+msgstr "INI-lêer"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:5
+msgid "Initialization"
+msgstr "Inisialisering"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:6
+msgid "Java Properties File"
+msgstr "Java .properties-lêer"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:7
+msgid "JavaScript error message file"
+msgstr "JavaScript-foutboodskaplêer"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:8
+msgid "OpenOffice.org Translation File"
+msgstr "OpenOffice.org-vertaallêer"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:9
+msgid "Qt Linguist Translation File"
+msgstr "Qt Linguist-vertaallêer"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:10
+msgid "Qt Message File"
+msgstr "Qt-boodskaplêer"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:11
+msgid "RC"
+msgstr "RC"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:12
+msgid "Resource Compiler"
+msgstr "Resource Compiler"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:13
+msgid "TBX"
+msgstr "TBX"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:14
+msgid "TBX Glossary"
+msgstr "TBX-termlys"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:15
+msgid "TMX"
+msgstr "TMX"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:16
+msgid "TMX Translation Memory"
+msgstr "TMX-vertaalgehue"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:17
+msgid "Tcl Translation File"
+msgstr "Tcl-vertaallêer"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:18
+msgid "TermBase eXchange"
+msgstr "TermBase eXchange"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:19
+msgid "Trados Tag Editor"
+msgstr "Trados-etiketredigeerder"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:20
+msgid "Translation Memory eXchange"
+msgstr "Translation Memory eXchange"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:21
+msgid "Wordfast Translation Memory"
+msgstr "Wordfast-vertaalgeheue"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:22
+msgid "XLIFF"
+msgstr "XLIFF"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:23
+msgid "XLIFF Translation File"
+msgstr "XLIFF-vertaallêer"
+
+#: ../share/virtaal/virtaal-mimetype.xml.in.h:24
+msgid "XML Localization Interchange File Format"
+msgstr "XML Localization Interchange File Format"
+
+#: ../virtaal/about.py:32
+msgid "© Copyright 2007-2008 Zuza Software Foundation"
+msgstr "© Kopiereg 2007-2008 Zuza Sagteware Stigting"
+
+#: ../virtaal/about.py:33
+msgid ""
+"Advanced Computer Aided Translation (CAT) tool for localization and "
+"translation"
+msgstr ""
+"Gevorderde program vir rekenaar gesteunde vertaling vir lokaliseerders en "
+"vertalers"
+
+#: ../virtaal/about.py:48
+msgid "VirTaal website"
+msgstr "VirTaal-webwerf"
+
+#: ../virtaal/about.py:54
+msgid "translator-credits"
+msgstr "Dwayne Bailey"
+
+#: ../virtaal/document.py:54
+msgid "Please enter the language code for the target language"
+msgstr ""
+
+#: ../virtaal/document.py:59 ../virtaal/document.py:65
+msgid "Please enter the number of noun forms (plurals) to use"
+msgstr ""
+
+#: ../virtaal/formats.py:31
+msgid "Choose a translation file"
+msgstr "Kies 'n vertaallêer"
+
+#: ../virtaal/formats.py:42
+msgid "All Supported Files"
+msgstr "Alle gesteunde lêers"
+
+#: ../virtaal/formats.py:60
+msgid "All Files"
+msgstr "Alle lêers"
+
+#: ../virtaal/main_window.py:197
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save your changes?"
+msgstr ""
+
+#: ../virtaal/main_window.py:199
+msgid "_Discard"
+msgstr ""
+
+#: ../virtaal/main_window.py:220
+msgid ""
+"You selected the currently open file for opening. Do you want to reload the "
+"file?"
+msgstr ""
+
+#: ../virtaal/main_window.py:284
+#, python-format
+msgid "VirTaal - %(current_file)s %(modified_marker)s"
+msgstr "VirTaal - %(current_file)s %(modified_marker)s"
+
+#: ../virtaal/main_window.py:312
+msgid "Please enter your name"
+msgstr "Tik jou naam in"
+
+#: ../virtaal/main_window.py:318
+msgid "Please enter your e-mail address"
+msgstr "Tik jou e-posaddress in"
+
+#: ../virtaal/main_window.py:324
+msgid "Please enter your team's information"
+msgstr "Tik jou span inligting in"
+
+#: ../virtaal/main_window.py:353
+msgid "Save"
+msgstr ""
+
+#: ../virtaal/modes.py:53
+msgid "Default"
+msgstr ""
+
+#: ../virtaal/modes.py:60
+msgid "Quick Translate"
+msgstr ""
+
+#: ../virtaal/store_grid.py:73
+msgid "The file did not contain anything to translate."
+msgstr ""
+
+#: ../virtaal/tips.py:25
+msgid ""
+"At the end of a translation, simply press <Enter> to continue with the next "
+"one."
+msgstr ""
+
+#. l10n: Refer to the translation of "Copy to target" to find the appropriate shortcut key to recommend
+#: ../virtaal/tips.py:27
+msgid ""
+"To copy the original string into the target field, simply press <Alt+C>."
+msgstr ""
+
+#: ../virtaal/tips.py:28
+msgid ""
+"When editing a fuzzy translation, the fuzzy marker will automatically be "
+"removed."
+msgstr ""
+
+#. l10n: Refer to the translation of "Fuzzy" to find the appropriate shortcut key to recommend
+#: ../virtaal/tips.py:30
+msgid "To mark the current translation as fuzzy, simply press <Alt+U>."
+msgstr ""
+
+#: ../virtaal/unit_layout.py:314
+msgid "F_uzzy"
+msgstr "_Wysig"
+
+#~ msgid "Save as..."
+#~ msgstr "Stoor as..."
Added: virtaal/branches/upstream/current/po/gtk20-lite.pot
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/po/gtk20-lite.pot?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/po/gtk20-lite.pot (added)
+++ virtaal/branches/upstream/current/po/gtk20-lite.pot Fri Oct 3 19:42:03 2008
@@ -1,0 +1,179 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Zuza Software Foundation (Translate.org.za)
+# This file is distributed under the same license as the Virtaal package.
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: GTK+ lite 2.0\n"
+"Report-Msgid-Bugs-To: translate-devel at lists.sourceforge.net\n"
+"POT-Creation-Date: 2008-07-25 18:31+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: LANGUAGE <LL at li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Translate to default:RTL if you want your widgets
+#. * to be RTL, otherwise translate to default:LTR.
+#. * Do *not* translate it to "predefinito:LTR", if it
+#. * it isn't default:LTR or default:RTL it will not work
+#.
+#. Configuration: Direction
+msgid "default:LTR"
+msgstr ""
+
+#. File->Open
+msgid "_Open"
+msgstr ""
+
+#. File->Save
+msgid "_Save"
+msgstr ""
+
+#. File->Save As
+msgid "Save _As"
+msgstr ""
+
+#. File->Quit
+msgid "_Quit"
+msgstr ""
+
+#. Help->About
+msgid "_About"
+msgstr ""
+
+#. About Dialog - Title
+msgid "About %s"
+msgstr ""
+
+#. About Dialog - Credits button
+msgid "C_redits"
+msgstr ""
+
+#. About Dialog - License button
+msgid "_License"
+msgstr ""
+
+#. About Dialog - Close button
+msgid "_Close"
+msgstr ""
+
+#. About Dialog - Credits dialog - Title
+msgid "Credits"
+msgstr ""
+
+#. About Dialog - Credits dialog - Tab - Written by
+msgid "Written by"
+msgstr ""
+
+#. About Dialog - Credits dialog - Tab - Translated by
+msgid "Translated by"
+msgstr ""
+
+#. About Dialog - License dialog - Title
+msgid "License"
+msgstr ""
+
+#. File dialog - Cancel button
+msgid "_Cancel"
+msgstr ""
+
+#. File dialog - Add button
+msgid "_Add"
+msgstr ""
+
+#. File dialog - Add button - tooltip
+msgid "Add the folder '%s' to the bookmarks"
+msgstr ""
+
+#. File dialog - Add button - tooltip
+msgid "Add the current folder to the bookmarks"
+msgstr ""
+
+#. File dialog - Remove button
+msgid "_Remove"
+msgstr ""
+
+#. File dialog - Remove button - tooltip
+msgid "Remove the bookmark '%s'"
+msgstr ""
+
+#. File dialog - Remove button - tooltip
+msgid "Remove the selected bookmark"
+msgstr "De geselecteerde bladwijzer verwijderen"
+
+#. File dialog - Location - Label
+msgid "_Location:"
+msgstr ""
+
+#. File dialog - Location - Open/Close button - Tooltip
+msgid "Type a file name"
+msgstr ""
+
+#. File dialog - Places - Grid label - Places
+msgid "_Places"
+msgstr ""
+
+#. File dialog - Places - Entry - Recently used
+msgid "Recently Used"
+msgstr ""
+
+#. File dialog - Places - Entry - Desktop
+msgid "Desktop"
+msgstr ""
+
+#. File dialog - Places - Right-Click - Remove
+msgid "Remove"
+msgstr ""
+
+#. File dialog - Places - Right-Click - Rename...
+msgid "Rename..."
+msgstr ""
+
+#. File dialog - Files - Grid label - Name
+msgid "Name"
+msgstr ""
+
+#. File dialog - Files - Grid label - Modified
+msgid "Modified"
+msgstr ""
+
+#. File dialog - Files - Table - Date formats - Today at
+msgid "Today at %H:%M"
+msgstr ""
+
+#. File dialog - Files - Table - Date formats - Yesterday at
+msgid "Yesterday at %H:%M"
+msgstr ""
+
+#. File dialog - Files - Right click - Show Hidden Files
+msgid "Show _Hidden Files"
+msgstr ""
+
+#. File dialog - Files - Right click - Add to Bookmarks
+msgid "_Add to Bookmarks"
+msgstr ""
+
+#. File dialog - File type list - tooltip
+msgid "Select which types of files are shown"
+msgstr ""
+
+#. File save dialog - Name:
+msgid "_Name:"
+msgstr ""
+
+#. File save dialog - Save in folder:
+msgid "Save in _folder:"
+msgstr ""
+
+#. File save dialog - Browse for other folders
+msgid "_Browse for other folders"
+msgstr ""
+
+#. File save dialog - Create folder button
+msgid "Create Fo_lder"
+msgstr ""
+
Added: virtaal/branches/upstream/current/po/intltool-update
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/po/intltool-update?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/po/intltool-update (added)
+++ virtaal/branches/upstream/current/po/intltool-update Fri Oct 3 19:42:03 2008
@@ -1,0 +1,9 @@
+#!/bin/bash
+
+packagename=$(egrep "^X-PACKAGENAME" Makevars | sed "s/X-PACKAGENAME = //g")
+package=$(egrep "^DOMAIN" Makevars | sed "s/DOMAIN = //g")
+
+XGETTEXT_ARGS='--copyright-holder="Zuza Software Foundation (Translate.org.za)" --package-name "'$packagename'" --package-version `egrep "^ver " ../'$package'/__version__.py | sed "s/ver = //;s/\"//g"`'
+export XGETTEXT_ARGS
+
+intltool-update $*
Propchange: virtaal/branches/upstream/current/po/intltool-update
------------------------------------------------------------------------------
svn:executable =
Added: virtaal/branches/upstream/current/po/testlocalisations
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/po/testlocalisations?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/po/testlocalisations (added)
+++ virtaal/branches/upstream/current/po/testlocalisations Fri Oct 3 19:42:03 2008
@@ -1,0 +1,20 @@
+#!/bin/bash
+
+./intltool-update --pot
+podebug -P --rewrite=xxx -f "" --progress=none virtaal.pot de_DE.po
+podebug -P --rewrite=xxx -f "" --progress=none gtk20-lite.pot de_DE-lite.po
+for po in $(ls *.po | egrep -v lite)
+do
+ modir=mo/$(basename $po .po)/LC_MESSAGES
+ gtklite=$(basename $po .po)-lite.po
+ mkdir -p $modir
+ msgfmt -o $modir/virtaal.mo $po
+ if [ -f $gtklite ]; then
+ msgfmt -o $modir/gtk20.mo $gtklite
+ fi
+done
+
+lang=$1
+export LANGUAGE=../../../$(pwd)/mo/${lang:-de_DE}
+echo $LANGUAGE
+run_virtaal.py
Propchange: virtaal/branches/upstream/current/po/testlocalisations
------------------------------------------------------------------------------
svn:executable =
Added: virtaal/branches/upstream/current/po/virtaal.pot
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/po/virtaal.pot?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/po/virtaal.pot (added)
+++ virtaal/branches/upstream/current/po/virtaal.pot Fri Oct 3 19:42:03 2008
@@ -1,0 +1,395 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Zuza Software Foundation (Translate.org.za)
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Virtaal 0.2-rc1\n"
+"Report-Msgid-Bugs-To: translate-devel at lists.sourceforge.net\n"
+"POT-Creation-Date: 2008-10-02 15:37+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: LANGUAGE <LL at li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../bin/virtaal:40
+msgid ""
+"You must specify a directory or a translation store file for --terminology"
+msgstr ""
+
+#: ../bin/virtaal:44
+#, c-format
+msgid "%prog [options] [translation_file]"
+msgstr ""
+
+#: ../bin/virtaal:47
+msgid "PROFILE"
+msgstr ""
+
+#: ../bin/virtaal:48
+msgid "Perform profiling, storing the result to the supplied filename."
+msgstr ""
+
+#: ../bin/virtaal:50
+msgid "LOG"
+msgstr ""
+
+#: ../bin/virtaal:51
+msgid "Turn on logging, storing the result to the supplied filename."
+msgstr ""
+
+#: ../bin/virtaal:53
+msgid "CONFIG"
+msgstr ""
+
+#: ../bin/virtaal:54
+msgid "Use the configuration file given by the supplied filename."
+msgstr ""
+
+#: ../bin/virtaal:55
+msgid "TERMINOLOGY"
+msgstr ""
+
+#: ../bin/virtaal:58
+msgid "Specify a directory containing terminology files"
+msgstr ""
+
+#: ../bin/virtaal:76
+msgid "Could not open log file '%(filename)s'"
+msgstr ""
+
+#: ../bin/virtaal:83
+msgid "Could not read configuration file '%(filename)s'"
+msgstr ""
+
+#: ../bin/virtaal:87
+msgid "invalid number of arguments"
+msgstr ""
+
+#: ../bin/virtaal:112
+msgid "Could not open profile file '%(filename)s'"
+msgstr ""
+
+#: ../share/applications/virtaal.desktop.in.h:1
+msgid ""
+"A translation tool to help a human translator translate files into other "
+"languages"
+msgstr ""
+
+#: ../share/applications/virtaal.desktop.in.h:2
+msgid "Translation Tool"
+msgstr ""
+
+#: ../share/applications/virtaal.desktop.in.h:3
+#: ../share/virtaal/virtaal.glade.h:2
+msgid "Virtaal"
+msgstr ""
+
+#: ../share/virtaal/virtaal.glade.h:1
+msgid "Report a _Bug"
+msgstr ""
+
+#: ../share/virtaal/virtaal.glade.h:3
+msgid "_File"
+msgstr ""
+
+#: ../share/virtaal/virtaal.glade.h:4
+msgid "_Help"
+msgstr ""
+
+#: ../share/virtaal/virtaal.glade.h:5
+msgid "_Localization Guide"
+msgstr ""
+
+#: ../share/virtaal/virtaal.glade.h:6
+msgid "_Online Help"
+msgstr ""
+
+#: ../share/virtaal/virtaal.glade.h:7
+msgid "_Recent Files"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:1
+msgid "C++ RC File"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:2
+msgid "Gettext Translation Template"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:3
+msgid "INI"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:4
+msgid "INI File"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:5
+msgid "Initialization"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:6
+msgid "Java Properties File"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:7
+msgid "JavaScript error message file"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:8
+msgid "OpenOffice.org Translation File"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:9
+msgid "Qt Linguist Translation File"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:10
+msgid "Qt Message File"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:11
+msgid "Qt Phrase Book"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:12
+msgid "RC"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:13
+msgid "Resource Compiler"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:14
+msgid "TBX"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:15
+msgid "TBX Glossary"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:16
+msgid "TMX"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:17
+msgid "TMX Translation Memory"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:18
+msgid "Tcl Translation File"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:19
+msgid "TermBase eXchange"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:20
+msgid "Trados Tag Editor"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:21
+msgid "Translation Memory eXchange"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:22
+msgid "Wordfast Translation Memory"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:23
+msgid "XLIFF"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:24
+msgid "XLIFF Translation File"
+msgstr ""
+
+#: ../share/mime/packages/virtaal-mimetype.xml.in.h:25
+msgid "XML Localization Interchange File Format"
+msgstr ""
+
+#: ../virtaal/about.py:34
+msgid "Copyright © 2007-2008 Zuza Software Foundation"
+msgstr ""
+
+#. l10n: Please retain the literal name "Virtaal", but feel free to
+#. additionally transliterate the name and to add a translation of "For Language", which is what the name means.
+#: ../virtaal/about.py:37
+msgid "Virtaal is a program for doing translation."
+msgstr ""
+
+#: ../virtaal/about.py:38
+msgid ""
+"The initial focus is on software translation (localisation or l10n), but we "
+"definitely intend it to be useful as a general purpose tool for Computer "
+"Aided Translation (CAT)."
+msgstr ""
+
+#: ../virtaal/about.py:52
+msgid "Virtaal website"
+msgstr ""
+
+#. l10n: Rather than translating, fill in the names of the translators
+#: ../virtaal/about.py:60
+msgid "translator-credits"
+msgstr ""
+
+#: ../virtaal/document.py:56
+msgid "Please enter the language code for the target language"
+msgstr ""
+
+#: ../virtaal/document.py:61
+msgid "Please enter the number of noun forms (plurals) to use"
+msgstr ""
+
+#: ../virtaal/document.py:67
+msgid "Please enter the plural equation to use"
+msgstr ""
+
+#: ../virtaal/formats.py:31
+msgid "Choose a translation file"
+msgstr ""
+
+#: ../virtaal/formats.py:42
+msgid "All Supported Files"
+msgstr ""
+
+#: ../virtaal/formats.py:60
+msgid "All Files"
+msgstr ""
+
+#: ../virtaal/main_window.py:171
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save your changes?"
+msgstr ""
+
+#: ../virtaal/main_window.py:173
+msgid "_Discard"
+msgstr ""
+
+#: ../virtaal/main_window.py:195
+msgid ""
+"You selected the currently open file for opening. Do you want to reload the "
+"file?"
+msgstr ""
+
+#: ../virtaal/main_window.py:244
+msgid "Error opening file:"
+msgstr ""
+
+#: ../virtaal/main_window.py:260
+#, python-format
+msgid "%(filename)s does not exist."
+msgstr ""
+
+#: ../virtaal/main_window.py:279
+#, python-format
+msgid "Virtaal - %(current_file)s %(modified_marker)s"
+msgstr ""
+
+#: ../virtaal/main_window.py:311
+msgid "Please enter your name"
+msgstr ""
+
+#: ../virtaal/main_window.py:317
+msgid "Please enter your e-mail address"
+msgstr ""
+
+#: ../virtaal/main_window.py:323
+msgid "Please enter your team's information"
+msgstr ""
+
+#: ../virtaal/main_window.py:351
+#, python-format
+msgid ""
+"Could not save file.\n"
+"\n"
+"%(error_message)s\n"
+"\n"
+"Try saving at a different location."
+msgstr ""
+
+#: ../virtaal/main_window.py:352
+msgid "Error"
+msgstr ""
+
+#: ../virtaal/main_window.py:362
+msgid "Save"
+msgstr ""
+
+#: ../virtaal/modes.py:81
+msgid "All"
+msgstr ""
+
+#: ../virtaal/modes.py:102
+msgid "Incomplete"
+msgstr ""
+
+#: ../virtaal/mode_selector.py:47
+msgid "_Mode: "
+msgstr ""
+
+#: ../virtaal/search_mode.py:37
+msgid "Search"
+msgstr ""
+
+#: ../virtaal/search_mode.py:51
+msgid "_Case sensitive"
+msgstr ""
+
+#: ../virtaal/search_mode.py:53
+msgid "_Regular expression"
+msgstr ""
+
+#: ../virtaal/store_grid.py:77
+msgid "The file did not contain anything to translate."
+msgstr ""
+
+#: ../virtaal/support/set_enumerator.py:62
+msgid "Top of page reached, continuing at the bottom"
+msgstr ""
+
+#: ../virtaal/support/set_enumerator.py:66
+msgid "End of page reached, continuing at the top"
+msgstr ""
+
+#: ../virtaal/tips.py:24
+msgid ""
+"At the end of a translation, simply press <Enter> to continue with the next "
+"one."
+msgstr ""
+
+#: ../virtaal/tips.py:25
+msgid ""
+"To copy the original string into the target field, simply press <Alt+Down>."
+msgstr ""
+
+#: ../virtaal/tips.py:26
+msgid ""
+"When editing a fuzzy translation, the fuzzy marker will automatically be "
+"removed."
+msgstr ""
+
+#. l10n: Refer to the translation of "Fuzzy" to find the appropriate shortcut key to recommend
+#: ../virtaal/tips.py:28
+msgid "To mark the current translation as fuzzy, simply press <Alt+U>."
+msgstr ""
+
+#: ../virtaal/tips.py:29
+msgid "Use Ctrl+Up or Ctrl+Down to move between translations."
+msgstr ""
+
+#: ../virtaal/tips.py:30
+msgid ""
+"Use Ctrl+PgUp or Ctrl+PgDown to move in large steps between translations."
+msgstr ""
+
+#: ../virtaal/unit_layout.py:362
+msgid "F_uzzy"
+msgstr ""
Added: virtaal/branches/upstream/current/setup.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/setup.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/setup.py (added)
+++ virtaal/branches/upstream/current/setup.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,375 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+from distutils.core import setup, Distribution, Command
+from virtaal.__version__ import ver as virtaal_version
+import glob
+import os
+import os.path as path
+import sys
+
+try:
+ import py2exe
+ build_exe = py2exe.build_exe.py2exe
+ Distribution = py2exe.Distribution
+except ImportError:
+ py2exe = None
+ build_exe = Command
+
+try:
+ import py2app
+except ImportError:
+ py2app = None
+
+PRETTY_NAME = "Virtaal"
+SOURCE_DATA_DIR = path.join('share')
+TARGET_DATA_DIR = path.join("share")
+
+virtaal_description="A tool to create program translations."
+
+classifiers = [
+ "Development Status :: 5 - Production/Stable",
+ "Environment :: Console",
+ "Intended Audience :: Developers",
+ "Intended Audience :: End Users/Desktop",
+ "Intended Audience :: Information Technology",
+ "License :: OSI Approved :: GNU General Public License (GPL)",
+ "Programming Language :: Python",
+ "Topic :: Software Development :: Localization",
+ "Topic :: Text Processing :: Linguistic"
+ "Operating System :: OS Independent",
+ "Operating System :: Microsoft :: Windows",
+ "Operating System :: Unix"
+]
+#TODO: add Natural Language classifiers
+
+mo_files=[]
+for f in glob.glob(path.join('po', '*.mo')):
+ lang = path.split(f[:-3])[1] # Get "af" from "po/af.mo"
+ mo_files.append(
+ ( path.join(TARGET_DATA_DIR, "locale", lang, "LC_MESSAGES", "virtaal.mo"), [f] )
+ )
+
+# Some of these depend on some files to be built externally before running
+# setup.py, like the .xml and .desktop files
+options = {
+ 'data_files': [
+ (path.join(TARGET_DATA_DIR, "virtaal"), glob.glob(path.join(SOURCE_DATA_DIR, "virtaal", "*.*"))),
+ (path.join(TARGET_DATA_DIR, "virtaal", "autocorr"), glob.glob(path.join(SOURCE_DATA_DIR, "virtaal", "autocorr", "*"))),
+ (path.join(TARGET_DATA_DIR, "icons"), glob.glob(path.join(SOURCE_DATA_DIR, "icons", "*.*"))),
+ ] + mo_files,
+ 'scripts': [
+ "bin/virtaal"
+ ],
+ 'packages': [
+ "virtaal",
+ "virtaal.support",
+ "virtaal.widgets"
+ ],
+}
+
+no_install_files = [
+ ['LICENSE', 'maketranslations']
+]
+
+no_install_dirs = ['po']
+
+#############################
+# WIN 32 specifics
+
+def get_compile_command():
+ try:
+ import _winreg
+ compile_key = _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, "innosetupscriptfile\\shell\\compile\\command")
+ compilecommand = _winreg.QueryValue(compile_key, "")
+ compile_key.Close()
+
+ except:
+ compilecommand = "compil32.exe"
+ return compilecommand
+
+def chop(dist_dir, pathname):
+ """returns the path relative to dist_dir"""
+ assert pathname.startswith(dist_dir)
+ return pathname[len(dist_dir):]
+
+def create_inno_script(name, _lib_dir, dist_dir, exe_files, other_files, version = "1.0"):
+ if not dist_dir.endswith(os.sep):
+ dist_dir += os.sep
+ exe_files = [chop(dist_dir, p) for p in exe_files]
+ other_files = [chop(dist_dir, p) for p in other_files]
+ pathname = path.join(dist_dir, name + os.extsep + "iss")
+
+# See http://www.jrsoftware.org/isfaq.php for more InnoSetup config options.
+ ofi = open(pathname, "w")
+ print >> ofi, r'''; WARNING: This script has been created by py2exe. Changes to this script
+; will be overwritten the next time py2exe is run!
+
+[Setup]
+AppName=%(name)s
+AppVerName=%(name)s %(version)s
+AppPublisher=Zuza Software Foundation
+AppPublisherURL=http://www.translate.org.za/
+AppVersion=%(version)s
+AppSupportURL=http://translate.sourceforge.net/
+;AppComments=
+;AppCopyright=Copyright (C) 2007-2008 Zuza Software Foundation
+DefaultDirName={pf}\%(name)s
+DefaultGroupName=%(name)s
+OutputBaseFilename=%(name)s-%(version)s-setup
+ChangesAssociations=yes
+SetupIconFile=%(icon_path)s
+
+[Files]''' % {'name': name, 'version': version, 'icon_path': path.join(TARGET_DATA_DIR, "icons", "virtaal.ico")}
+ for fpath in exe_files + other_files:
+ print >> ofi, r'Source: "%s"; DestDir: "{app}\%s"; Flags: ignoreversion' % (fpath, os.path.dirname(fpath))
+ print >> ofi, r'''
+[Icons]
+Name: "{group}\%(name)s Translation Editor"; Filename: "{app}\virtaal.exe";
+Name: "{group}\%(name)s (uninstall)"; Filename: "{uninstallexe}"''' % {'name': name}
+
+# For now we don't worry about install scripts
+# if install_scripts:
+# print >> ofi, r"[Run]"
+#
+# for fpath in install_scripts:
+# print >> ofi, r'Filename: "{app}\%s"; WorkingDir: "{app}"; Parameters: "-install"' % fpath
+#
+# print >> ofi
+# print >> ofi, r"[UninstallRun]"
+#
+# for fpath in install_scripts:
+# print >> ofi, r'Filename: "{app}\%s"; WorkingDir: "{app}"; Parameters: "-remove"' % fpath
+
+ # File associations. Note the directive "ChangesAssociations=yes" above
+ # that causes the installer to tell Explorer to refresh associations.
+ # This part might cause the created installer to need administrative
+ # privileges. An alternative might be to rather write to
+ # HKCU\Software\Classes, but this won't be system usable then. Didn't
+ # see a way to test and alter the behaviour.
+
+ # For each file type we should have something like this:
+ #
+ #;File extension:
+ #Root: HKCR; Subkey: ".po"; ValueType: string; ValueName: ""; ValueData: "virtaal_po"; Flags: uninsdeletevalue
+ #;Description of the file type
+ #Root: HKCR; Subkey: "virtaal_po"; ValueType: string; ValueName: ""; ValueData: "Gettext PO"; Flags: uninsdeletekey
+ #;Icon to use in Explorer
+ #Root: HKCR; Subkey: "virtaal_po\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\share\icons\virtaal.ico"
+ #;The command to open the file
+ #Root: HKCR; Subkey: "virtaal_po\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\virtaal.exe"" ""%1"""
+
+ print >> ofi, "[Registry]"
+ from translate.storage import factory
+ for description, extentions, _mimetypes in factory.supported_files():
+ # We skip those types where we depend on mime types, not extentions
+ if not extentions:
+ continue
+ # Form a key from the first extention for internal only
+ key = extentions[0]
+ # Associate each extention with the file type
+ for extention in extentions:
+ print >> ofi, r'Root: HKCR; Subkey: ".%(extention)s"; ValueType: string; ValueName: ""; ValueData: "virtaal_%(key)s"; Flags: uninsdeletevalue' % {'extention': extention, 'key': key}
+ print >> ofi, r'''Root: HKCR; Subkey: "virtaal_%(key)s"; ValueType: string; ValueName: ""; ValueData: "%(description)s"; Flags: uninsdeletekey
+Root: HKCR; Subkey: "virtaal_%(key)s\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\share\icons\virtaal.ico"
+Root: HKCR; Subkey: "virtaal_%(key)s\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\virtaal.exe"" ""%%1"""''' % {'key': key, 'description': description}
+
+ # Show a "Launch Virtaal" checkbox on the last installer screen
+ print >> ofi, r'''
+[Run]
+Filename: "{app}\virtaal.exe"; Description: "{cm:LaunchProgram,%(name)s}"; Flags: nowait postinstall skipifsilent''' % {'name': name}
+ print >> ofi
+ ofi.close()
+ return pathname
+
+def compile_inno_script(script_path):
+ """compiles the script using InnoSetup"""
+ shell_compile_command = get_compile_command()
+ compile_command = shell_compile_command.replace('"%1"', script_path)
+ result = os.system(compile_command)
+ if result:
+ print "Error compiling iss file"
+ print "Opening iss file, use InnoSetup GUI to compile manually"
+ os.startfile(script_path)
+
+class BuildWin32Installer(build_exe):
+ """distutils class that first builds the exe file(s), then creates a Windows installer using InnoSetup"""
+ description = "create an executable installer for MS Windows using InnoSetup and py2exe"
+ user_options = getattr(build_exe, 'user_options', []) + \
+ [('install-script=', None,
+ "basename of installation script to be run after installation or before deinstallation")]
+
+ def initialize_options(self):
+ build_exe.initialize_options(self)
+
+ def run(self):
+ # First, let py2exe do it's work.
+ build_exe.run(self)
+ # create the Installer, using the files py2exe has created.
+ exe_files = self.windows_exe_files + self.console_exe_files
+ print "*** creating the inno setup script***"
+ script_path = create_inno_script(PRETTY_NAME, self.lib_dir, self.dist_dir, exe_files, self.lib_files,
+ version=self.distribution.metadata.version)
+ print "*** compiling the inno setup script***"
+ compile_inno_script(script_path)
+ # Note: By default the final setup.exe will be in an Output subdirectory.
+
+def find_gtk_bin_directory():
+ GTK_NAME = "libgtk"
+ # Look for GTK in the user's Path as well as in some familiar locations
+ paths = os.environ['Path'].split(';') + [r'C:\GTK\bin', r'C:\Program Files\GTK\bin']
+ for p in paths:
+ files = [path.join(p, f) for f in os.listdir(p) if path.isfile(path.join(p, f)) and f.startswith(GTK_NAME)]
+ if len(files) > 0:
+ return p
+ raise Exception("""Could not find the GTK runtime.
+Please place bin directory of your GTK installation in the program path.""")
+
+def find_gtk_files():
+ def parent(dir_path):
+ return path.abspath(path.join(path.abspath(dir_path), '..'))
+
+ def strip_leading_path(leadingPath, p):
+ return p[len(leadingPath) + 1:]
+
+ data_files = []
+ gtk_path = parent(find_gtk_bin_directory())
+ for dir_path in [path.join(gtk_path, p) for p in ('etc', 'share', 'lib')]:
+ for dir_name, _, files in os.walk(dir_path):
+ files = [path.abspath(path.join(dir_name, f)) for f in files]
+ if len(files) > 0:
+ data_files.append((strip_leading_path(gtk_path, dir_name), files))
+ return data_files
+
+def add_win32_options(options):
+ """This function is responsible for finding data files and setting options necessary
+ to build executables and installers under Windows.
+
+ @return: A 2-tuple (data_files, options), where data_files is a list of Windows
+ specific data files (this would include the GTK binaries) and where
+ options are the options required by py2exe."""
+ if py2exe != None and ('py2exe' in sys.argv or 'innosetup' in sys.argv):
+ options['data_files'].extend(find_gtk_files())
+
+ py2exe_options = {
+ "packages": ["encodings", "virtaal"],
+ "compressed": True,
+ "excludes": ["PyLucene", "Tkconstants", "Tkinter", "tcl", "translate.misc._csv"],
+ "dist_dir": "virtaal-win32",
+ "includes": ["lxml", "lxml._elementpath", "psyco", "cairo", "pango", "pangocairo", "atk", "gobject", "gtk.keysyms"],
+ "optimize": 2,
+ }
+ innosetup_options = py2exe_options.copy()
+ options.update({
+ "windows": [
+ {
+ 'script': 'bin/virtaal',
+ 'icon_resources': [(1, path.join(SOURCE_DATA_DIR, "icons", "virtaal.ico"))],
+ }
+ ],
+ 'zipfile': "virtaal.zip",
+ "options": {
+ "py2exe": py2exe_options,
+ "innosetup": innosetup_options
+ },
+ 'cmdclass': {
+ "py2exe": build_exe,
+ "innosetup": BuildWin32Installer
+ }
+ })
+ return options
+
+def add_mac_options(options):
+ # http://svn.pythonmac.org/py2app/py2app/trunk/doc/index.html#tweaking-your-info-plist
+ # http://developer.apple.com/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/PListKeys.html
+ if py2app is None:
+ return options
+ options.update({"options": {
+ "app": "bin/virtaal",
+ "py2app": {
+ #"semi_standalone": True,
+ "compressed": True,
+ "argv_emulation": True,
+ "plist": {
+ "CFBundleGetInfoString": virtaal_description,
+ "CFBundleGetInfoString": "Virtaal",
+ "CFBundleIconFile": "virtaal.icns",
+ "CFBundleShortVersionString": virtaal_version,
+ #"LSHasLocalizedDisplayName": "1",
+ #"LSMinimumSystemVersion": ???,
+ "NSHumanReadableCopyright": "Copyright (C) 2007-2008 Zuza Software Foundation",
+ "CFBundleDocumentTypes": [{
+ "CFBundleTypeExtensions": [extention.lstrip("*.") for extention in extentions],
+ "CFBundleTypeIconFile": "virtaal.icns",
+ "CFBundleTypeMIMETypes": mimetypes,
+ "CFBundleTypeName": description, #????
+ } for description, extentions, mimetypes in factory.supported_files()]
+ }
+ }
+ }})
+ return options
+
+def add_freedesktop_options(options):
+ options['data_files'].extend([
+ (path.join(TARGET_DATA_DIR, "mime", "packages"), glob.glob(path.join(SOURCE_DATA_DIR, "mime", "packages", "*.xml"))),
+ (path.join(TARGET_DATA_DIR, "applications"), glob.glob(path.join(SOURCE_DATA_DIR, "applications", "*.desktop"))),
+ ])
+ return options
+
+#############################
+# General functions
+
+def add_platform_specific_options(options):
+ if sys.platform == 'win32':
+ return add_win32_options(options)
+ if sys.platform == 'darwin':
+ return add_mac_options(options)
+ else:
+ return add_freedesktop_options(options)
+
+def create_manifest(data_files, extra_files, extra_dirs):
+ f = open('MANIFEST.in', 'w+')
+ for data_file_list in [d[1] for d in data_files] + extra_files:
+ f.write("include %s\n" % (" ".join( data_file_list )))
+ for dir in extra_dirs:
+ f.write("graft %s\n" % (dir))
+ f.close()
+
+def main(options):
+ options = add_platform_specific_options(options)
+ create_manifest(options['data_files'], no_install_files, no_install_dirs)
+ setup(name="virtaal",
+ version=virtaal_version,
+ license="GNU General Public License (GPL)",
+ description=virtaal_description,
+ long_description="""Virtaal is used to create program translations.
+
+It uses the Translate Toolkit to get access to translation files and therefore
+can edit a variety of files (including PO and XLIFF files).""",
+ author="Translate.org.za",
+ author_email="translate-devel at lists.sourceforge.net",
+ url="http://translate.sourceforge.net/wiki/virtaal/index",
+ download_url="http://sourceforge.net/project/showfiles.php?group_id=91920&package_id=270877",
+ platforms=["any"],
+ classifiers=classifiers,
+ **options)
+
+if __name__ == '__main__':
+ main(options)
Propchange: virtaal/branches/upstream/current/setup.py
------------------------------------------------------------------------------
svn:executable =
Added: virtaal/branches/upstream/current/share/applications/virtaal.desktop
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/applications/virtaal.desktop?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/share/applications/virtaal.desktop (added)
+++ virtaal/branches/upstream/current/share/applications/virtaal.desktop Fri Oct 3 19:42:03 2008
@@ -1,0 +1,19 @@
+[Desktop Entry]
+Version=1.0
+Type=Application
+Name=Virtaal
+GenericName=Translation Tool
+GenericName[af]=Vertaalprogram
+Comment=A translation tool to help a human translator translate files into other languages
+Comment[af]='n Vertaal program om 'n vertaaler te help om lêers na ander tale te vertaal.
+TryExec=virtaal
+Exec=virtaal %f
+Icon=virtaal
+MimeType=text/x-gettext-translation;text/x-gettext-translation-template;application/x-gettext;application/x-gettext-translation;application/x-xliff+xml;application/x-xliff;text/x-wordfast;application/x-tmx;application/x-tbx;application/x-linguist;application/x-qph;
+# Not yet supported
+# application/x-sdf;
+# application/x-qm;
+# Monolingual
+# application/x-ini;
+# application/x-properties;
+Categories=Development;Translation;GTK;
Added: virtaal/branches/upstream/current/share/icons/virtaal.ico
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/icons/virtaal.ico?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/icons/virtaal.ico
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/icons/virtaal.png
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/icons/virtaal.png?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/icons/virtaal.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/mime/packages/virtaal-mimetype.xml
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/mime/packages/virtaal-mimetype.xml?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/share/mime/packages/virtaal-mimetype.xml (added)
+++ virtaal/branches/upstream/current/share/mime/packages/virtaal-mimetype.xml Fri Oct 3 19:42:03 2008
@@ -1,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
+
+ <mime-type type="application/x-tmx">
+ <sub-class-of type="application/xml"/>
+ <comment>TMX Translation Memory</comment>
+ <comment xml:lang="af">TMX-vertaalgehue</comment>
+ <acronym>TMX</acronym>
+ <acronym xml:lang="af">TMX</acronym>
+ <expanded-acronym>Translation Memory eXchange</expanded-acronym>
+ <expanded-acronym xml:lang="af">Translation Memory eXchange</expanded-acronym>
+ <glob pattern="*.tmx"/>
+ <magic priority="80">
+ <match value="<tmx" type="string" offset="0:256"/>
+ </magic>
+
+ </mime-type>
+
+ <mime-type type="application/x-tbx">
+ <sub-class-of type="application/xml"/>
+ <comment>TBX Glossary</comment>
+ <comment xml:lang="af">TBX-termlys</comment>
+ <acronym>TBX</acronym>
+ <acronym xml:lang="af">TBX</acronym>
+ <expanded-acronym>TermBase eXchange</expanded-acronym>
+ <expanded-acronym xml:lang="af">TermBase eXchange</expanded-acronym>
+ <glob pattern="*.tbx"/>
+ <magic priority="80">
+ <match value="<martif type="TBX"" type="string" offset="0:256"/>
+ </magic>
+ </mime-type>
+
+ <mime-type type="text/x-wordfast">
+ <sub-class-of type="text/tab-separated-values"/>
+ <comment>Wordfast Translation Memory</comment>
+ <comment xml:lang="af">Wordfast-vertaalgeheue</comment>
+ <glob pattern="*.txt"/>
+ <magic priority="80">
+ <match value="%Wordfast TM" type="string" offset="0:256"/>
+ <match value="\0%\0W\0o\0r\0d\0f\0a\0s\0t\0 \0T\0M" type="string" offset="0:256"/>
+ </magic>
+ </mime-type>
+
+
+ <mime-type type="application/x-linguist">
+ <sub-class-of type="application/xml"/>
+ <comment>Qt Linguist Translation File</comment>
+ <comment xml:lang="af">Qt Linguist-vertaallêer</comment>
+ <glob pattern="*.ts"/>
+ </mime-type>
+
+ <mime-type type="application/x-qm">
+ <comment>Qt Message File</comment>
+ <comment xml:lang="af">Qt-boodskaplêer</comment>
+ <glob pattern="*.qm"/>
+ </mime-type>
+
+ <mime-type type="application/x-qph">
+ <comment>Qt Phrase Book</comment>
+ <glob pattern="*.qph"/>
+ <magic priority="50">
+ <match value="<QPH>" type="string" offset="0:256"/>
+ </magic>
+ </mime-type>
+
+ <mime-type type="text/x-ini">
+ <sub-class-of type="text/plain"/>
+ <comment>INI File</comment>
+ <comment xml:lang="af">INI-lêer</comment>
+ <acronym>INI</acronym>
+ <acronym xml:lang="af">INI</acronym>
+ <expanded-acronym>Initialization</expanded-acronym>
+ <expanded-acronym xml:lang="af">Inisialisering</expanded-acronym>
+ <glob pattern="*.ini"/>
+
+ <alias type="zz-application/zz-winassoc-ini"/>
+ </mime-type>
+
+ <mime-type type="text/x-properties">
+ <sub-class-of type="text/plain"/>
+ <comment>Java Properties File</comment>
+ <comment xml:lang="af">Java .properties-lêer</comment>
+ <glob pattern="*.properties"/>
+ </mime-type>
+
+ <mime-type type="text/x-sdf">
+ <sub-class-of type="text/tab-separated-values"/>
+ <comment>OpenOffice.org Translation File</comment>
+ <comment xml:lang="af">OpenOffice.org-vertaallêer</comment>
+ <glob pattern="*.sdf"/>
+ </mime-type>
+
+ <mime-type type="application/x-xliff+xml">
+ <sub-class-of type="application/xml"/>
+ <comment>XLIFF Translation File</comment>
+ <comment xml:lang="af">XLIFF-vertaallêer</comment>
+ <acronym>XLIFF</acronym>
+ <acronym xml:lang="af">XLIFF</acronym>
+ <expanded-acronym>XML Localization Interchange File Format</expanded-acronym>
+ <expanded-acronym xml:lang="af">XML Localization Interchange File Format</expanded-acronym>
+ <glob pattern="*.xlf"/>
+ <glob pattern="*.xliff"/>
+ <magic priority="80">
+ <match value="<xliff" type="string" offset="0:256"/>
+ </magic>
+ <root-XML namespaceURI='urn:oasis:names:tc:xliff:document:1.' localName='xliff'/>
+ <alias type="application/x-xliff"/>
+ </mime-type>
+
+ <mime-type type="text/x-rc">
+ <sub-class-of type="text/x-csrc"/>
+ <comment>C++ RC File</comment>
+ <comment xml:lang="af">C++ RC-lêer</comment>
+ <acronym>RC</acronym>
+ <acronym xml:lang="af">RC</acronym>
+ <expanded-acronym>Resource Compiler</expanded-acronym>
+ <expanded-acronym xml:lang="af">Resource Compiler</expanded-acronym>
+ <glob pattern="*.rc"/>
+ </mime-type>
+
+ <mime-type type="text/x-msg">
+ <sub-class-of type="text/x-tcl"/>
+ <comment>Tcl Translation File</comment>
+ <comment xml:lang="af">Tcl-vertaallêer</comment>
+ <glob pattern="*.msg"/>
+ <magic priority="50">
+ <match value="::msgcat::mcset" type="string" offset="0:160"/>
+ </magic>
+ </mime-type>
+
+ <mime-type type="application/x-javascript-msg">
+ <sub-class-of type="application/javascript"/>
+ <comment>JavaScript error message file</comment>
+ <comment xml:lang="af">JavaScript-foutboodskaplêer</comment>
+ <glob pattern="*.msg"/>
+ <magic priority="50">
+ <match value="MSG_DEF(" type="string" offset="0:2560"/>
+ </magic>
+ </mime-type>
+
+ <mime-type type="text/x-gettext-translation-template">
+ <sub-class-of type="text/plain"/>
+ <comment>Gettext Translation Template</comment>
+ <comment xml:lang="af">Gettext-vertaalsjabloon</comment>
+ <glob pattern="*.pot"/>
+ <magic priority="50">
+ <match value="msgid" type="string" offset="0:256"/>
+ <match value="msgstr" type="string" offset="0:256"/>
+ <match value="msgctxt" type="string" offset="0:256"/>
+ </magic>
+ </mime-type>
+
+ <mime-type type="application/x-ttx">
+ <sub-class-of type="application/xml"/>
+ <comment>Trados Tag Editor</comment>
+ <comment xml:lang="af">Trados-etiketredigeerder</comment>
+ <glob pattern="*.ttx"/>
+ <magic priority="50">
+ <match value="<TRADOStag" type="string" offset="0:256"/>
+ </magic>
+ </mime-type>
+
+</mime-info>
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_af-ZA.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_af-ZA.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_af-ZA.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_bg-BG.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_bg-BG.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_bg-BG.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_cs-CZ.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_cs-CZ.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_cs-CZ.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_da-DK.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_da-DK.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_da-DK.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_de-DE.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_de-DE.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_de-DE.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_en-GB.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_en-GB.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_en-GB.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_en-US.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_en-US.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_en-US.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_en-ZA.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_en-ZA.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_en-ZA.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_es-ES.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_es-ES.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_es-ES.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_fi-FI.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_fi-FI.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_fi-FI.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_fr-FR.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_fr-FR.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_fr-FR.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_hu-HU.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_hu-HU.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_hu-HU.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_it-IT.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_it-IT.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_it-IT.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_ja-JP.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_ja-JP.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_ja-JP.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_ko-KR.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_ko-KR.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_ko-KR.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_nl-NL.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_nl-NL.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_nl-NL.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_pl-PL.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_pl-PL.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_pl-PL.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_pt-BR.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_pt-BR.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_pt-BR.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_pt-PT.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_pt-PT.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_pt-PT.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_ru-RU.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_ru-RU.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_ru-RU.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_sk-SK.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_sk-SK.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_sk-SK.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_sl-SI.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_sl-SI.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_sl-SI.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_sv-SE.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_sv-SE.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_sv-SE.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_tr-TR.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_tr-TR.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_tr-TR.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_vi-VN.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_vi-VN.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_vi-VN.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_zh-CN.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_zh-CN.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_zh-CN.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_zh-TW.dat
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/autocorr/acor_zh-TW.dat?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/autocorr/acor_zh-TW.dat
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/virtaal.glade
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/virtaal.glade?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/share/virtaal/virtaal.glade (added)
+++ virtaal/branches/upstream/current/share/virtaal/virtaal.glade Fri Oct 3 19:42:03 2008
@@ -1,0 +1,206 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Thu Sep 25 21:29:41 2008
+ Version: 3.0.1
+ Date: Thu Dec 6 12:30:34 2007
+ User: fwolff
+ Host: dhcppc3
+-->
+<glade-interface>
+ <widget class="GtkWindow" id="MainWindow">
+ <property name="width_request">620</property>
+ <property name="height_request">400</property>
+ <property name="title" translatable="yes">Virtaal</property>
+ <signal name="destroy" handler="on_mainwindow_destroy"/>
+ <signal name="delete_event" handler="on_mainwindow_delete"/>
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkMenuBar" id="menubar1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkMenuItem" id="menuitem1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_File</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem2">
+ <property name="visible">True</property>
+ <property name="label">gtk-open</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="on_open_activate"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="save_menuitem">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="label">gtk-save</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="on_save_activate"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="saveas_menuitem">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="label">gtk-save-as</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="on_saveas_activate"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="recent_files">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Recent Files</property>
+ <property name="use_underline">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separatormenuitem2">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem5">
+ <property name="visible">True</property>
+ <property name="label">gtk-quit</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="on_quit"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="menuitem_help">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Help</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu_help">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImageMenuItem" id="menuitem_documentation">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Online Help</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_menuitem_documentation_activate"/>
+ <child internal-child="image">
+ <widget class="GtkImage" id="menu-item-image3">
+ <property name="visible">True</property>
+ <property name="stock">gtk-help</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menuitem_localization_guide">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Localization Guide</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_localization_guide_activate"/>
+ <child internal-child="image">
+ <widget class="GtkImage" id="menu-item-image2">
+ <property name="stock">gtk-dialog-info</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menuitem_report_bug">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Report a _Bug</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_menuitem_report_bug_activate"/>
+ <child internal-child="image">
+ <widget class="GtkImage" id="menu-item-image4">
+ <property name="visible">True</property>
+ <property name="stock">gtk-dialog-error</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separator1">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem_about">
+ <property name="visible">True</property>
+ <property name="label">gtk-about</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="on_about_activate"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="mode_bar">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <child>
+ <widget class="GtkTreeView" id="unitTree">
+ <property name="visible">True</property>
+ <property name="rules_hint">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkStatusbar" id="status_bar">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
Added: virtaal/branches/upstream/current/share/virtaal/virtaal_logo.png
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/virtaal_logo.png?rev=1394&op=file
==============================================================================
Binary file - no diff available.
Propchange: virtaal/branches/upstream/current/share/virtaal/virtaal_logo.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: virtaal/branches/upstream/current/share/virtaal/virtaal_logo.svg
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/share/virtaal/virtaal_logo.svg?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/share/virtaal/virtaal_logo.svg (added)
+++ virtaal/branches/upstream/current/share/virtaal/virtaal_logo.svg Fri Oct 3 19:42:03 2008
@@ -1,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="744.09448819"
+ height="1052.3622047"
+ id="svg3340"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docname="virtaal8.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ inkscape:export-filename="/home/heather/Desktop/logo development/Virtaal/virtaal7.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs3342">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective3348" />
+ <filter
+ inkscape:collect="always"
+ id="filter3913">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="3.8099069"
+ id="feGaussianBlur3915" />
+ </filter>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.979899"
+ inkscape:cx="193.51701"
+ inkscape:cy="700.8122"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1280"
+ inkscape:window-height="953"
+ inkscape:window-x="0"
+ inkscape:window-y="24" />
+ <metadata
+ id="metadata3345">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <path
+ style="fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;opacity:0.0122449"
+ id="path3261"
+ d="M 169.99997,212.2255 C 113.64304,212.2255 67.904251,240.0149 67.904251,274.24704 C 67.904251,308.47925 113.64304,336.2686 169.99997,336.2686 C 175.71516,336.2686 181.29572,336.00382 186.75586,335.45461 C 185.12512,344.19143 182.5698,350.25716 178.95292,355.55871 C 174.57325,361.97823 167.76469,366.90502 158.17236,371.5118 C 182.03491,373.07811 194.46989,367.72348 206.46863,359.95397 C 224.77582,348.09951 227.67997,331.04221 227.90627,325.28053 C 254.77334,314.10565 272.09569,295.50545 272.09575,274.24704 C 272.09575,240.01484 226.357,212.2255 169.99997,212.2255 z" />
+ <path
+ style="opacity:1;fill:#53536c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter3913)"
+ d="M 163.7403,364.53614 C 170.07125,361.10179 177.12538,354.18411 180.13308,348.46044 C 181.9771,344.95129 185.64285,334.59551 185.64285,332.89534 C 185.64285,332.87308 178.81249,332.83447 170.46428,332.80954 C 145.08129,332.73376 126.89883,328.8858 108.35368,319.66507 C 98.937464,314.98328 93.424714,311.11953 87.042924,304.72883 C 77.911394,295.58458 73.554774,286.77328 72.943534,276.21277 C 72.504364,268.62514 73.548094,263.78438 77.263744,256.17571 C 82.573134,245.30349 95.495744,234.02053 110.91339,226.79557 C 155.06964,206.10326 219.55908,212.92866 249.84606,241.49986 C 260.96486,251.98875 265.80158,261.92293 265.80158,274.27088 C 265.80157,280.52866 264.28191,286.1579 260.77055,292.90711 C 255.84453,302.37546 241.80288,314.48533 229.04013,320.27223 C 225.47378,321.88928 224.18986,322.85495 223.95127,324.0996 C 221.55695,336.59037 219.33132,340.99322 211.35713,349.01408 C 199.436,361.00499 184.93906,366.86026 167.28011,366.81665 L 159.57142,366.79763 L 163.7403,364.53614 z M 186.92856,302.40711 C 187.43591,301.89977 187.78571,299.45899 187.78571,296.42627 L 187.78571,291.30258 L 184.63616,291.23935 C 182.74742,291.20144 181.15621,291.57426 180.66123,292.17068 C 179.53431,293.52853 179.51173,297.25849 180.62231,298.59666 C 181.24173,299.34301 181.2762,299.69283 180.73031,299.69283 C 180.28935,299.69283 179.92856,300.11068 179.92856,300.6214 C 179.92856,302.18576 181.53174,303.26426 183.85713,303.26426 C 185.07499,303.26426 186.45713,302.87854 186.92856,302.40711 L 186.92856,302.40711 z M 214.7857,302.40711 C 215.29305,301.89977 215.64285,299.45899 215.64285,296.42627 L 215.64285,291.30258 L 212.49331,291.23935 C 210.60456,291.20144 209.01336,291.57426 208.51837,292.17068 C 207.39145,293.52853 207.36888,297.25849 208.47946,298.59666 C 209.09888,299.34301 209.13334,299.69283 208.58745,299.69283 C 208.14649,299.69283 207.78571,300.11068 207.78571,300.6214 C 207.78571,302.18576 209.38888,303.26426 211.71428,303.26426 C 212.93213,303.26426 214.31428,302.87854 214.78571,302.40711 L 214.7857,302.40711 z M 138.76078,298.92671 C 141.02254,297.14762 141.20773,294.54343 139.21428,292.54997 C 136.56714,289.90283 132.58204,291.11248 131.68496,294.83546 C 131.32463,296.3308 131.62936,297.17283 133.04197,298.58546 C 135.25031,300.79378 136.30703,300.85683 138.76081,298.9267 L 138.76078,298.92671 z M 167.48698,299.69283 C 168.97861,299.69283 169.21428,299.35808 169.21428,297.23933 C 169.21428,292.88304 168.12928,291.1214 165.44624,291.1214 C 163.13706,291.1214 161.35713,292.15518 161.35713,293.4964 C 161.35713,293.85978 162.32142,293.96426 163.49999,293.72854 C 164.70878,293.48679 165.64285,293.60354 165.64285,293.9964 C 165.64285,294.37944 165.06428,294.69283 164.35713,294.69283 C 161.54171,294.69283 160.27421,298.27464 162.60713,299.63812 C 163.29463,300.03994 164.28521,300.21662 164.80841,300.03076 C 165.33161,299.84489 166.53697,299.69283 167.48698,299.69283 z M 197.78571,295.33208 C 197.78571,291.63913 197.6151,291.1214 196.39821,291.1214 C 195.27701,291.1214 194.96855,291.70286 194.79106,294.15095 C 194.63084,296.3609 194.23325,297.24465 193.32142,297.41761 C 192.27626,297.61586 192.07142,297.11081 192.07142,294.33568 C 192.07142,291.55508 191.86864,291.05745 190.82142,291.26814 C 189.82821,291.46798 189.58186,292.23186 189.62224,294.98669 C 189.68371,299.18111 190.79663,300.20929 194.85613,299.82216 L 197.78571,299.54277 L 197.78571,295.33208 z M 204.81356,299.69283 C 206.65371,299.69283 206.71492,299.56703 206.46421,296.29997 C 206.32101,294.4339 205.87754,292.50533 205.47874,292.01426 C 204.09666,290.31243 199.21428,291.13746 199.21428,293.07282 C 199.21428,293.89663 199.72905,294.05416 201.35713,293.72854 C 204.22526,293.15492 204.06625,293.72277 200.99999,295.00393 C 199.32358,295.70438 198.49999,296.51944 198.49999,297.47803 C 198.49999,299.0757 200.49205,300.54913 201.95127,300.03076 C 202.47447,299.84489 203.7625,299.69283 204.81356,299.69283 z M 223.34104,299.29518 C 226.4596,297.11087 224.70041,291.1214 220.94031,291.1214 C 216.89138,291.1214 215.54624,297.64118 219.21428,299.48731 C 221.47063,300.62292 221.44364,300.62418 223.34106,299.29518 L 223.34104,299.29518 z M 125.64285,297.54997 C 125.64285,295.64521 125.88094,295.40711 127.78571,295.40711 C 129.45237,295.40711 129.92856,295.08966 129.92856,293.97854 C 129.92856,292.86743 129.45237,292.54997 127.78571,292.54997 C 126.35713,292.54997 125.64285,292.19283 125.64285,291.47854 C 125.64285,290.73024 126.39682,290.40711 128.14285,290.40711 C 129.88888,290.40711 130.64285,290.08398 130.64285,289.33568 C 130.64285,288.51317 129.73015,288.26426 126.71428,288.26426 L 122.78571,288.26426 L 122.78571,293.97854 C 122.78571,299.21663 122.90476,299.69283 124.21428,299.69283 C 125.32539,299.69283 125.64285,299.21663 125.64285,297.54997 z M 144.21428,297.12595 C 144.21428,295.1598 144.5486,294.47166 145.64285,294.18551 C 146.43351,293.97873 147.07142,293.21121 147.07142,292.46666 C 147.07142,291.37338 146.53625,291.1214 144.21428,291.1214 L 141.35713,291.1214 L 141.35713,295.40711 C 141.35713,299.21663 141.51586,299.69283 142.78571,299.69283 C 143.94926,299.69283 144.21428,299.21663 144.21428,297.12596 L 144.21428,297.12595 z M 160.64285,298.6214 C 160.64285,297.84759 159.8492,297.54997 157.78571,297.54997 L 154.92856,297.54997 L 154.92856,292.90711 C 154.92856,288.74045 154.78204,288.26426 153.49999,288.26426 C 152.19047,288.26426 152.07142,288.74045 152.07142,293.97854 L 152.07142,299.69283 L 156.35713,299.69283 C 159.69047,299.69283 160.64285,299.45473 160.64285,298.6214 z M 173.49999,296.41901 C 173.49999,292.20329 175.19126,292.45091 175.50535,296.71263 C 175.68217,299.11184 175.99548,299.69283 177.11249,299.69283 C 178.29666,299.69283 178.49999,299.18226 178.49999,296.20886 C 178.49999,292.04598 177.66706,291.19286 173.65671,291.24821 L 170.64285,291.28981 L 170.64285,295.49132 C 170.64285,299.21663 170.80476,299.69283 172.07142,299.69283 C 173.2922,299.69283 173.49999,299.21663 173.49999,296.41902 L 173.49999,296.41901 z M 107.74967,281.20506 C 109.30028,280.77241 109.71762,279.8256 111.41768,272.88341 L 113.33601,265.04997 L 113.41801,273.44283 L 113.49999,281.83568 L 116.89285,281.82474 C 118.75892,281.81873 120.69448,281.55437 121.19409,281.23728 C 121.82549,280.83655 122.24119,277.44918 122.55737,270.12851 L 123.01228,259.59626 L 118.43471,260.09636 C 115.88313,260.37511 114.11363,260.32439 114.43668,259.98176 C 114.75541,259.64368 116.68399,259.1993 118.72239,258.99424 L 122.42856,258.6214 L 122.64803,254.76871 L 122.86749,250.91601 L 119.51261,251.37585 C 117.66744,251.62876 115.55975,251.83568 114.82887,251.83568 C 113.69148,251.83568 113.49999,252.41186 113.49999,255.83395 L 113.49999,259.83223 L 109.40107,259.58394 L 105.30216,259.33568 L 104.52456,263.97854 L 103.74696,268.6214 L 103.20628,265.04997 C 102.25904,258.79282 102.49388,259.0405 97.933534,259.48908 C 95.691524,259.70961 93.745004,259.98459 93.607954,260.10015 C 93.470894,260.2157 94.413594,265.15347 95.702834,271.07296 L 98.046894,281.83568 L 102.02344,281.76449 C 104.21054,281.72533 106.78735,281.47359 107.74968,281.20507 L 107.74967,281.20506 z M 130.10713,281.37722 L 132.78571,280.93448 L 132.78571,275.40112 C 132.78571,269.40147 133.14531,268.7338 136.79663,267.95397 L 139.02184,267.47873 L 139.37628,273.00187 C 139.68994,277.88916 139.95229,278.71556 141.6552,280.18033 C 143.04055,281.37198 144.46511,281.83568 146.7405,281.83568 C 149.5357,281.83568 149.95441,281.62426 150.36004,280.00808 L 150.81876,278.18048 L 152.33793,279.59798 C 154.37856,281.50202 157.30571,282.14276 159.87373,281.24755 C 161.21016,280.78166 162.07133,280.76399 162.21649,281.19948 C 162.35351,281.61058 164.09765,281.69397 166.54444,281.4064 L 170.64285,280.92471 L 170.67079,277.98736 L 170.69878,275.04997 L 171.71898,277.39815 C 173.10046,280.57771 177.08644,282.2995 180.79713,281.31953 C 182.2877,280.92588 183.54313,280.89366 183.66058,281.24603 C 183.77741,281.59656 185.60091,281.62491 187.79201,281.31026 L 191.71428,280.74701 L 191.91709,272.6315 C 192.14703,263.42872 191.53595,261.72011 187.39595,259.99031 C 184.63277,258.83578 178.72516,258.65672 176.11678,259.64843 C 174.77627,260.15808 174.23403,261.03346 173.84971,263.30824 C 173.53889,265.14785 173.62896,266.47394 174.08378,266.75503 C 174.52406,267.02716 174.12226,267.83606 173.09006,268.75546 L 171.35713,270.29901 L 171.35713,268.18726 C 171.35713,262.3229 167.63646,258.97854 161.11222,258.97854 C 155.10802,258.97854 153.68036,259.57886 153.16616,262.3198 C 152.91082,263.68076 152.52568,265.25359 152.31026,265.81498 C 152.07594,266.42566 152.35761,266.83568 153.01148,266.83568 C 153.76556,266.83568 153.4571,267.48298 152.01648,268.9236 C 150.86811,270.07196 149.92856,271.69806 149.92856,272.53718 C 149.92856,273.3763 149.60713,273.8642 149.21428,273.6214 C 148.08601,272.92409 148.31941,267.54997 149.47796,267.54997 C 150.05318,267.54997 150.63827,266.44681 150.89867,264.8714 C 151.62311,260.48855 151.47405,259.69283 149.92856,259.69283 C 148.73188,259.69283 148.49999,259.21663 148.49999,256.75926 C 148.49999,254.69102 148.23663,253.93498 147.60713,254.19617 C 140.93472,256.96473 139.21428,257.89138 139.21428,258.71663 C 139.21428,259.37077 138.31881,259.69283 136.49999,259.69283 C 135.00713,259.69283 133.39999,260.07854 132.92856,260.54997 C 132.26189,261.21663 132.07142,261.20871 132.07142,260.51433 C 132.07142,259.87881 130.88789,259.68326 127.96428,259.83576 L 123.85713,260.04997 L 123.65995,270.94283 L 123.46281,281.83568 L 125.44566,281.82781 C 126.53626,281.8235 128.63392,281.62073 130.10713,281.37722 z M 201.66327,280.71323 C 202.60717,279.76932 202.78571,277.36798 202.78571,265.61615 L 202.78571,251.64151 L 199.47171,252.09573 C 197.64903,252.34556 195.55975,252.54997 194.82887,252.54997 C 193.57646,252.54997 193.49999,253.39233 193.49999,267.19283 L 193.49999,281.83568 L 197.02041,281.83568 C 199.26839,281.83568 200.94651,281.42998 201.66326,280.71323 L 201.66327,280.71323 z M 222.81291,257.3714 C 225.01092,256.26301 226.5176,254.8181 227.66786,252.71548 C 228.58517,251.03866 230.28689,249.17484 231.44944,248.57366 C 234.07908,247.21383 236.35179,243.59341 236.35179,240.76426 C 236.35181,231.51252 219.29903,225.92932 207.08706,231.18278 C 196.27994,235.83186 196.53118,246.26853 207.54945,250.391 C 209.72925,251.20656 213.40629,252.07177 215.72065,252.31366 C 220.54483,252.8179 220.9831,253.67851 217.78571,256.36893 C 216.60713,257.36063 215.64285,258.35349 215.64285,258.57528 C 215.64285,259.55422 219.90264,258.83897 222.81293,257.3714 L 222.81291,257.3714 z"
+ id="path3899" />
+ <path
+ style="fill:#80e5ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path3378"
+ d="M 164.99997,209.36836 C 111.40305,209.36836 67.904253,236.03813 67.904253,268.89108 C 67.904253,301.74408 111.40305,328.41381 164.99997,328.41381 C 170.43527,328.41381 175.74253,328.1597 180.93526,327.63262 C 179.38439,336.01743 176.95421,341.83878 173.51446,346.92673 C 169.34928,353.08762 162.87416,357.8159 153.7516,362.23707 C 176.44552,363.74029 188.27151,358.60139 199.68263,351.1449 C 217.09325,339.76806 219.85517,323.39799 220.07039,317.86844 C 245.62168,307.1438 262.09569,289.29299 262.09575,268.89108 C 262.09575,236.03808 218.59699,209.36836 164.99997,209.36836 z" />
+ <text
+ xml:space="preserve"
+ style="font-size:15.66961764999999929px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#004455;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Arial;-inkscape-font-specification:Arial"
+ x="121.81638"
+ y="304.1788"
+ id="text3263"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3265"
+ x="121.81638"
+ y="304.1788"
+ style="font-size:15.66961764999999929px;font-weight:bold;fill:#004455;fill-opacity:1;stroke:none;stroke-opacity:1;-inkscape-font-specification:Arial Bold">For Language</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:15.66961765px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Arial;-inkscape-font-specification:Arial"
+ x="120.26348"
+ y="303.12317"
+ id="text8730"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan8732"
+ x="120.26348"
+ y="303.12317"
+ style="font-size:15.66961765px;font-weight:bold;fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1;-inkscape-font-specification:Arial Bold">For Language</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:34.82137299px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#006680;fill-opacity:1;stroke:none;stroke-width:0.87053436px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Rough Draft;-inkscape-font-specification:Rough Draft"
+ x="100.8779"
+ y="286.63895"
+ id="text3267"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3269"
+ x="100.8779"
+ y="286.63895"
+ style="font-size:34.82137299px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#006680;stroke:none;stroke-width:0.87053436;stroke-opacity:1;font-family:GROBOLD;-inkscape-font-specification:GROBOLD">virtaal</tspan></text>
+ <path
+ style="fill:#004455;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path3271"
+ d="M 218.27555,234.47918 C 208.05011,234.47918 199.75123,239.56735 199.75123,245.83517 C 199.75123,252.103 208.05011,257.19116 218.27555,257.19116 C 219.31252,257.19116 220.32506,257.14268 221.31575,257.04212 C 221.01987,258.64181 220.55623,259.75243 219.89998,260.72313 C 219.10533,261.89853 217.86998,262.80061 216.12954,263.6441 C 220.45918,263.93089 222.71539,262.95047 224.89245,261.52789 C 228.21412,259.35737 228.74105,256.23422 228.78211,255.17927 C 233.65689,253.13318 236.79987,249.72753 236.79988,245.83517 C 236.79988,239.56734 228.50101,234.47918 218.27555,234.47918 z" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path4953"
+ d="M 217.38017,232.53035 C 207.15473,232.53035 198.85585,237.61852 198.85585,243.88634 C 198.85585,250.15417 207.15473,255.24233 217.38017,255.24233 C 218.41714,255.24233 219.42968,255.19385 220.42037,255.09329 C 220.12449,256.69298 219.66085,257.8036 219.0046,258.7743 C 218.20995,259.9497 216.9746,260.85178 215.23416,261.69527 C 219.5638,261.98206 221.82001,261.00164 223.99707,259.57906 C 227.31874,257.40854 227.84567,254.28539 227.88673,253.23044 C 232.76151,251.18435 235.90449,247.7787 235.9045,243.88634 C 235.9045,237.61851 227.60563,232.53035 217.38017,232.53035 z" />
+ <text
+ xml:space="preserve"
+ style="font-size:34.82137299px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffdd55;fill-opacity:1;stroke:#ff6600;stroke-width:0.87053436px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Rough Draft;-inkscape-font-specification:Rough Draft"
+ x="97.511887"
+ y="284.3403"
+ id="text8718"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan8720"
+ x="97.511887"
+ y="284.3403"
+ style="font-size:34.82137299px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffdd55;stroke:#ff6600;stroke-width:0.87053436;stroke-opacity:1;font-family:GROBOLD;-inkscape-font-specification:GROBOLD">virtaal</tspan></text>
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:none;fill-opacity:0.99551571;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path2489"
+ sodipodi:cx="154.64285"
+ sodipodi:cy="288.07648"
+ sodipodi:rx="146.78572"
+ sodipodi:ry="97.85714"
+ d="M 301.42857,288.07648 A 146.78572,97.85714 0 1 1 7.857132,288.07648 A 146.78572,97.85714 0 1 1 301.42857,288.07648 z"
+ transform="matrix(0.9221411,0,0,0.9160584,7.0403189,15.967317)" />
+ </g>
+</svg>
Added: virtaal/branches/upstream/current/virtaal/__init__.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/__init__.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/__init__.py (added)
+++ virtaal/branches/upstream/current/virtaal/__init__.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,19 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
Added: virtaal/branches/upstream/current/virtaal/__version__.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/__version__.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/__version__.py (added)
+++ virtaal/branches/upstream/current/virtaal/__version__.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,22 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+"""This file contains the version."""
+ver = "0.2-rc1"
Added: virtaal/branches/upstream/current/virtaal/about.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/about.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/about.py (added)
+++ virtaal/branches/upstream/current/virtaal/about.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,83 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+import gtk
+import os
+import __version__
+from support import openmailto
+import pan_app
+
+
+class About(gtk.AboutDialog):
+ def __init__(self, parent):
+ gtk.AboutDialog.__init__(self)
+ self._register_uri_handlers()
+ self.set_name("Virtaal")
+ self.set_version(__version__.ver)
+ self.set_copyright(_(u"Copyright © 2007-2008 Zuza Software Foundation"))
+ # l10n: Please retain the literal name "Virtaal", but feel free to
+ # additionally transliterate the name and to add a translation of "For Language", which is what the name means.
+ self.set_comments(_("Virtaal is a program for doing translation.") + "\n\n" +
+ _("The initial focus is on software translation (localisation or l10n), but we definitely intend it to be useful as a general purpose tool for Computer Aided Translation (CAT)."))
+ self.set_license("""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 Library General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, see <http://www.gnu.org/licenses/>.""")
+ self.set_website("http://translate.sourceforge.net/wiki/virtaal/index")
+ self.set_website_label(_("Virtaal website"))
+ self.set_authors([
+ "Friedel Wolff <friedel at translate.org.za>",
+ "Wynand Winterbach <wynand at translate.org.za>",
+ "Dwayne Bailey <dwayne at translate.org.za>",
+ "Walter Leibbrandt <walter at translate.org.za>",
+ ])
+ # l10n: Rather than translating, fill in the names of the translators
+ self.set_translator_credits(_("translator-credits"))
+ self.set_icon(parent.get_icon())
+ self.set_logo(gtk.gdk.pixbuf_new_from_file(pan_app.get_abs_data_filename(["virtaal", "virtaal_logo.png"])))
+ self.set_artists([
+ "Heather Bailey <heather at translate.org.za>",
+ ])
+ # FIXME entries that we may want to add
+ #self.set_documenters()
+ self.connect ("response", lambda d, r: d.destroy())
+ self.show()
+
+ def on_url(self, dialog, uri, data):
+ if data == "mail":
+ openmailto.mailto(uri)
+ elif data == "url":
+ openmailto.open(uri)
+
+ def _register_uri_handlers(self):
+ """Register the URL and email handlers
+
+ Use open and mailto from virtaal.support.openmailto
+ """
+ gtk.about_dialog_set_url_hook(self.on_url, "url")
+ gtk.about_dialog_set_email_hook(self.on_url, "mail")
Added: virtaal/branches/upstream/current/virtaal/autocompletor.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/autocompletor.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/autocompletor.py (added)
+++ virtaal/branches/upstream/current/virtaal/autocompletor.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,285 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+"""Contains the AutoCompletor class."""
+
+import gobject
+import gtk
+import re
+
+import undo_buffer
+
+
+class AutoCompletor(object):
+ """
+ Does auto-completion of registered words in registered widgets.
+ """
+
+ wordsep_re = re.compile(r'\W+', re.UNICODE)
+
+ DEFAULT_COMPLETION_LENGTH = 4 # The default minimum length of a word that may
+ # be auto-completed.
+
+ def __init__(self, word_list=[], comp_len=DEFAULT_COMPLETION_LENGTH):
+ """Constructor.
+
+ @type word_list: iterable
+ @param word_list: A list of words that should be auto-completed.
+ """
+ assert isinstance(word_list, list)
+ self.comp_len = comp_len
+ self._word_list = list(set(word_list))
+ self.widgets = set()
+
+ def add_widget(self, widget):
+ """Add a widget to the list of widgets to do auto-completion for."""
+ if widget in self.widgets:
+ return # Widget already added
+
+ if isinstance(widget, gtk.TextView):
+ self._add_text_view(widget)
+ return
+
+ raise ValueError("Widget type %s not supported." % (type(widget)))
+
+ def add_words(self, words):
+ """Add a word or words to the list of words to auto-complete."""
+ if isinstance(words, basestring):
+ self._word_list.append(words)
+ else:
+ self._word_list += list(words)
+ self._word_list = list(set(self._word_list)) # Remove duplicates
+
+ def add_words_from_store(self, store):
+ """Collect all words from the given translation store to use for
+ auto-completion.
+
+ @type store: translate.storage.pypo.pofile
+ @param store: The translation store to collect words from.
+ """
+ wordcounts = {}
+
+ for unit in store.units:
+ if not unit.target:
+ continue
+ for word in self.wordsep_re.split(unit.target):
+ if len(word) > self.comp_len:
+ try:
+ wordcounts[word] += 1
+ except KeyError:
+ wordcounts[word] = 1
+
+ # Sort found words according to frequency
+ wordlist = wordcounts.items()
+ wordlist.sort(key=lambda x:x[1])
+
+ wordlist = [items[0] for items in wordlist]
+
+ self._word_list += list(set(wordlist))
+
+ def autocomplete(self, word):
+ for w in self._word_list:
+ if w.startswith(word):
+ return w, w[len(word):]
+ return None, u''
+
+ def clear_widgets(self):
+ """Release all registered widgets from the spell of auto-completion."""
+ for w in set(self.widgets):
+ self.remove_widget(w)
+
+ def clear_words(self):
+ """Remove all registered words; effectively turns off auto-completion."""
+ self.words.clear()
+
+ def remove_widget(self, widget):
+ """Remove a widget (currently only C{gtk.TextView}s are accepted) from
+ the list of widgets to do auto-correction for.
+ """
+ if isinstance(widget, gtk.TextView) and widget in self.widgets:
+ self._remove_textview(widget)
+
+ def remove_words(self, words):
+ """Remove a word or words from the list of words to auto-complete."""
+ if isinstance(words, basestring):
+ self._word_list.remove(words)
+ else:
+ for w in words:
+ try:
+ self._word_list.remove(w)
+ except KeyError:
+ pass
+
+ def _add_text_view(self, textview):
+ """Add the given I{gtk.TextView} to the list of widgets to do auto-
+ correction on.
+ """
+ id_dict_names = (
+ '_textbuffer_insert_ids',
+ '_textbuffer_delete_ids',
+ '_textview_button_press_ids',
+ '_textview_focus_out_ids',
+ '_textview_key_press_ids',
+ '_textview_move_cursor_ids'
+ )
+ for name in id_dict_names:
+ if not hasattr(self, name):
+ setattr(self, name, {})
+
+ buffer = textview.get_buffer()
+ handler_id = buffer.connect('insert-text', self._on_insert_text)
+ self._textbuffer_insert_ids[buffer] = handler_id
+
+ handler_id = buffer.connect('delete-range', self._on_delete_range)
+ self._textbuffer_delete_ids[buffer] = handler_id
+
+ handler_id = textview.connect('button-press-event', self._on_textview_button_press)
+ self._textview_button_press_ids[textview] = handler_id
+
+ handler_id = textview.connect('key-press-event', self._on_textview_keypress)
+ self._textview_key_press_ids[textview] = handler_id
+
+ handler_id = textview.connect('focus-out-event', self._on_textview_focus_out)
+ self._textview_focus_out_ids[textview] = handler_id
+
+ handler_id = textview.connect('move-cursor', self._on_textview_move_cursor)
+ self._textview_move_cursor_ids[textview] = handler_id
+
+ self.widgets.add(textview)
+
+ def _check_delete_selection(self, buffer):
+ """Deletes the current selection if said selection was created by the auto-completor."""
+ suggestion = getattr(buffer, '_suggestion', None)
+ if suggestion:
+ buffer.delete_selection(False, True)
+ buffer._suggestion = None
+
+ def _on_insert_text(self, buffer, iter, text, length):
+ if self.wordsep_re.match(text):
+ return
+ # We are only interested in single character insertions, otherwise we
+ # react similarly for paste and similar events
+ if len(text.decode('utf-8')) > 1:
+ return
+ prefix = unicode(buffer.get_text(buffer.get_start_iter(), iter) + text)
+ postfix = unicode(buffer.get_text(iter, buffer.get_end_iter()))
+ lastword = self.wordsep_re.split(prefix)[-1]
+
+ if len(lastword) >= self.comp_len:
+ completed_word, word_postfix = self.autocomplete(lastword)
+ if completed_word == lastword:
+ buffer._suggestion = None
+ return
+
+ if completed_word:
+ completed_prefix = prefix[:-len(lastword)] + completed_word
+ # Updating of the buffer is deferred until after this signal
+ # and its side effects are taken care of. We abuse
+ # gobject.idle_add for that.
+ def suggest_completion():
+ def insert_action():
+ buffer.insert_at_cursor(word_postfix)
+ buffer.handler_block(self._textbuffer_insert_ids[buffer])
+ undo_buffer.execute_without_signals(buffer, insert_action)
+ buffer.handler_unblock(self._textbuffer_insert_ids[buffer])
+ sel_iter_start = buffer.get_iter_at_offset(len(prefix))
+ sel_iter_end = buffer.get_iter_at_offset(len(prefix+word_postfix))
+ buffer.select_range(sel_iter_start, sel_iter_end)
+ buffer._suggestion = (sel_iter_start, sel_iter_end)
+ return False
+
+ gobject.idle_add(suggest_completion)
+ else:
+ buffer._suggestion = None
+ else:
+ buffer._suggestion = None
+
+ def _on_delete_range(self, buf, start_iter, end_iter):
+ # If we are deleting the suggestion, we don't want it in the undo_stack
+ suggestion = getattr(buf, '_suggestion', None)
+ if suggestion:
+ selection = buf.get_selection_bounds()
+ if selection and suggestion[0].equal(selection[0]) and suggestion[1].equal(selection[1]):
+ # Not pretty, but it works
+ getattr(buf, "__undo_stack").pop()
+ return False
+ else:
+ self._check_delete_selection(buf)
+ buf._suggestion = None
+
+ def _on_textview_button_press(self, textview, event):
+ self._check_delete_selection(textview.get_buffer())
+
+ def _on_textview_focus_out(self, textview, event):
+ self._check_delete_selection(textview.get_buffer())
+
+ def _on_textview_move_cursor(self, textview, step_size, count, expand_selection):
+ self._check_delete_selection(textview.get_buffer())
+
+ def _on_textview_keypress(self, textview, event):
+ """Catch tabs to the C{gtk.TextView} and make it keep the current selection."""
+ iters = textview.get_buffer().get_selection_bounds()
+
+ if not iters:
+ return False
+ if event.keyval == gtk.keysyms.Tab:
+ buf = textview.get_buffer()
+ completion = buf.get_text(iters[0], iters[1])
+ buf.delete(iters[0], iters[1])
+ buf.insert_at_cursor(completion)
+ return True
+ elif event.state & gtk.gdk.CONTROL_MASK and \
+ event.keyval == gtk.keysyms.Z or event.keyval== gtk.keysyms.BackSpace:
+ # An undo/delete event will unselect the suggestion and make it hang
+ # around. Therefore weneed to remove the suggestion manually.
+ self._check_delete_selection(textview.get_buffer())
+ return False
+
+ def _remove_textview(self, textview):
+ """Remove the given C{gtk.TextView} from the list of widgets to do
+ auto-correction on.
+ """
+ if not hasattr(self, '_textbuffer_insert_ids'):
+ return
+ # Disconnect the "insert-text" event handler
+ buffer = textview.get_buffer()
+ buffer.disconnect(self._textbuffer_insert_ids[buffer])
+
+ if not hasattr(self, '_textbuffer_delete_ids'):
+ return
+ # Disconnect the "delete-range" event handler
+ buffer.disconnect(self._textbuffer_delete_ids[buffer])
+
+ if not hasattr(self, '_textview_focus_out_ids'):
+ return
+ # Disconnect the "focus-out-event" event handler
+ textview.disconnect(self._textview_focus_out_ids[textview])
+
+ if not hasattr(self, '_textview_key_press_ids'):
+ return
+ # Disconnect the "key-press-event" event handler
+ textview.disconnect(self._textview_key_press_ids[textview])
+
+ if not hasattr(self, '_textview_move_cursor_ids'):
+ return
+ # Disconnect the "move-cursor" event handler
+ textview.disconnect(self._textview_move_cursor_ids[textview])
+
+ self.widgets.remove(textview)
Added: virtaal/branches/upstream/current/virtaal/autocorrector.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/autocorrector.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/autocorrector.py (added)
+++ virtaal/branches/upstream/current/virtaal/autocorrector.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,239 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+"""Contains the AutoCorrector class."""
+
+import gobject
+import gtk
+import os
+import re
+import zipfile
+from lxml import etree
+
+import undo_buffer
+
+
+class AutoCorrector(object):
+ """
+ Does auto-correction on editable text widgets using OpenOffice.org auto-
+ correction files.
+ """
+
+ wordsep_re = re.compile('\W+', re.UNICODE)
+
+ REPLACEMENT, REGEX = range(2)
+
+ def __init__(self, lang='', acorpath=None):
+ """Create a new AutoCorrector instance and load the OpenOffice.org
+ auto-correction diction for language code 'lang'.
+
+ @type lang: str
+ @param lang: The code of the language to load auto-correction data
+ for. See M{load_dictionary} for more information about how this
+ parameter is used.
+ @type acorpath: str
+ @param acorpath: The path to the directory containing the
+ OpenOffice.org auto-correction data files (acor_*.dat).
+ """
+ self.lang = None
+ if acorpath is None or not os.path.isdir(acorpath):
+ acorpath = os.path.curdir
+ self.acorpath = acorpath
+ self.load_dictionary(lang)
+ self.widgets = set()
+
+ def add_widget(self, widget):
+ """Add a widget (currently only C{gtk.TextView}s are accepted) to the
+ list of widgets to do auto-correction for.
+ """
+ if not self.correctiondict:
+ return # No dictionary to work with, so we can't handle any widgets
+
+ if widget in self.widgets:
+ return # Widget already added
+
+ if isinstance(widget, gtk.TextView):
+ self._add_textview(widget)
+ return
+
+ raise ValueError("Widget type %s not supported." % (type(widget)))
+
+ def autocorrect(self, src, endindex, inserted=u''):
+ """Apply auto-correction to source string.
+
+ @type src: basestring
+ @param src: The candidate-string for auto-correction.
+ @type endindex: int
+ @param endindex: The logical end of the string. ie. The part of the
+ string _before_ this index tested for the presence of a
+ correctable string.
+ @type inserted: basestring
+ @param inserted: The string that was inserted at I{endindex}
+
+ @rtype: 2-tuple
+ @return: The corrected substring (C{src[:endindex]}) (or None if no
+ corrections were made) and the postfix
+ (C{inserted + src[endindex:]}).
+ """
+ if not self.correctiondict:
+ return None, u''
+
+ candidate = src[:endindex]
+ postfix = inserted + src[endindex:]
+
+ for key in self.correctiondict:
+ if self.correctiondict[key][self.REGEX].match(candidate):
+ replacement = self.correctiondict[key][self.REPLACEMENT]
+ corrected = re.sub(r'%s$' % (re.escape(key)), replacement, candidate)
+ return corrected, postfix
+
+ return None, postfix # No corrections done
+
+ def clear_widgets(self):
+ """Removes references to all widgets that is being auto-corrected."""
+ for w in set(self.widgets):
+ self.remove_widget(w)
+
+ def load_dictionary(self, lang):
+ """Load the OpenOffice.org auto-correction dictionary for language
+ 'lang'.
+
+ OpenOffice.org's auto-correction data files are in named in the
+ format "acor_I{lang}-I{country}.dat", where I{lang} is the ISO
+ language code and I{country} the country code. This function can
+ handle (for example) "af", "af_ZA" or "af-ZA" to load the Afrikaans
+ data file. Here are the steps taken in trying to find the correct
+ data file:
+ - Underscores are replaced with hyphens in C{lang} ("af_ZA" ->
+ "af-ZA").
+ - The file for C{lang} is opened ("acor_af-ZA.dat").
+ - If the open fails, the language code ("af") is extracted and the
+ first file found starting with "acor_af" and ending in ".dat" is
+ used.
+
+ These steps imply that if "af" is given as lang, the data file
+ "acor_af-ZA.dat" will end up being loaded.
+ """
+ # Change "af_ZA" to "af-ZA", which OOo uses to store acor files.
+ if lang == self.lang:
+ return
+
+ if not lang:
+ self.correctiondict = {}
+ self.lang = ''
+ return
+
+ lang = lang.replace('_', '-')
+ try:
+ acor = zipfile.ZipFile(os.path.join(self.acorpath, 'acor_%s.dat' % lang))
+ except IOError, _exc:
+ # Try to find a file that starts with 'acor_%s' % (lang[0]) (where
+ # lang[0] is the part of lang before the '-') and ends with '.dat'
+ langparts = lang.split('-')
+ filenames = [fn for fn in os.listdir(self.acorpath) if fn.startswith('acor_%s' % langparts[0])
+ and fn.endswith('.dat')]
+ for fn in filenames:
+ try:
+ acor = zipfile.ZipFile(os.path.join(self.acorpath, fn))
+ break
+ except IOError:
+ pass
+
+ else:
+ # If no acceptable auto-correction file was found, we create an
+ # empty dictionary.
+ self.correctiondict = {}
+ self.lang = ''
+ return
+
+ xmlstr = acor.read('DocumentList.xml')
+ xml = etree.fromstring(xmlstr)
+ # Sample element from DocumentList.xml (it has no root element!):
+ # <block-list:block block-list:abbreviated-name="teh" block-list:name="the"/>
+ # This means that xml.iterchildren() will return an iterator over all
+ # of <block-list> elements and entry.values() will return a 2-tuple
+ # with the values of the "abbreviated-name" and "name" attributes.
+ # That is how I got to the simple line below.
+ self.correctiondict = dict([entry.values() for entry in xml.iterchildren()])
+
+ # Add auto-correction regex for each loaded word.
+ for key, value in self.correctiondict.items():
+ self.correctiondict[key] = (value, re.compile(r'.*\b%s$' % (re.escape(key)), re.UNICODE))
+
+ self.lang = lang
+ return
+
+ def remove_widget(self, widget):
+ """Remove a widget (currently only C{gtk.TextView}s are accepted) from
+ the list of widgets to do auto-correction for.
+ """
+ if not self.correctiondict:
+ return
+
+ if isinstance(widget, gtk.TextView) and widget in self.widgets:
+ self._remove_textview(widget)
+
+ def set_widgets(self, widget_collection):
+ """Replace the widgets being auto-corrected with the collection given."""
+ self.clear_widgets()
+ for w in widget_collection:
+ self.add_widget(w)
+
+ def _add_textview(self, textview):
+ """Add the given I{gtk.TextView} to the list of widgets to do auto-
+ correction on.
+ """
+ if not hasattr(self, '_textbuffer_handler_ids'):
+ self._textbuffer_handler_ids = {}
+
+ handler_id = textview.get_buffer().connect(
+ 'insert-text',
+ self._on_insert_text
+ )
+ self._textbuffer_handler_ids[textview] = handler_id
+ self.widgets.add(textview)
+
+ def _on_insert_text(self, buffer, iter, text, length):
+ bufftext = unicode(buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter()))
+ iteroffset = iter.get_offset() + len(text)
+
+ if not self.wordsep_re.split(text)[-1]:
+ res, postfix = self.autocorrect(bufftext, iter.get_offset(), text)
+ if res is not None:
+ # Updating of the buffer is deferred until after this signal
+ # and its side effects are taken care of. We abuse
+ # gobject.idle_add for that.
+ def correct_text():
+ buffer.props.text = u''.join([res, postfix])
+ buffer.place_cursor( buffer.get_iter_at_offset(len(res) + len(text)) )
+ undo_buffer.merge_actions(buffer, iteroffset)
+ return False
+
+ gobject.idle_add(correct_text)
+
+ def _remove_textview(self, textview):
+ """Remove the given C{gtk.TextView} from the list of widgets to do
+ auto-correction on.
+ """
+ if not hasattr(self, '_textbuffer_handler_ids'):
+ return
+ # Disconnect the "insert-text" event handler
+ textview.get_buffer().disconnect(self._textbuffer_handler_ids[textview])
+ self.widgets.remove(textview)
Added: virtaal/branches/upstream/current/virtaal/document.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/document.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/document.py (added)
+++ virtaal/branches/upstream/current/virtaal/document.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,189 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+import logging
+
+import gobject
+
+from translate.storage.poheader import poheader
+from translate.storage import ts2 as ts
+from translate.storage import statsdb, factory
+from translate.filters import checks
+from translate.lang import factory as langfactory
+
+import pan_app
+from widgets.entry_dialog import EntryDialog
+from mode_selector import ModeSelector
+
+
+def get_document(obj):
+ """See whether obj contains an attribute called 'document'.
+ If it does, return the attribute value. Otherwise, see if
+ it has a parent (via the attribute 'parent') and ask the
+ parent if it contains 'document'. If there is no parent
+ and no 'document' attribute, return None."""
+ if not hasattr(obj, 'document'):
+ if hasattr(obj, 'parent'):
+ return get_document(getattr(obj, 'parent'))
+ else:
+ return None
+ else:
+ return getattr(obj, 'document')
+
+def compute_nplurals(store):
+ def ask_for_language_details():
+ def get_content_lang():
+ if pan_app.settings.language["contentlang"] != None:
+ return pan_app.settings.language["contentlang"]
+ else:
+ return EntryDialog(_("Please enter the language code for the target language"))
+
+ def ask_for_number_of_plurals():
+ while True:
+ try:
+ entry = EntryDialog(_("Please enter the number of noun forms (plurals) to use"))
+ return int(entry)
+ except ValueError, _e:
+ pass
+
+ def ask_for_plurals_equation():
+ return EntryDialog(_("Please enter the plural equation to use"))
+
+ lang = langfactory.getlanguage(get_content_lang())
+ nplurals = lang.nplurals or ask_for_number_of_plurals()
+ if nplurals > 1 and lang.pluralequation == "0":
+ return nplurals, ask_for_plurals_equation()
+ else:
+ # Note that if nplurals == 1, the default equation "0" is correct
+ return nplurals, lang.pluralequation
+
+ # FIXME this needs to be pushed back into the stores, we don't want to import each format
+ if isinstance(store, poheader):
+ nplurals, _pluralequation = store.getheaderplural()
+ if nplurals is None:
+ # Nothing in the header, so let's use the global settings
+ settings = pan_app.settings
+ nplurals = settings.language["nplurals"]
+ pluralequation = settings.language["plural"]
+ if not (int(nplurals) > 0 and pluralequation):
+ nplurals, pluralequation = ask_for_language_details()
+ pan_app.settings.language["nplurals"] = nplurals
+ pan_app.settings.language["plural"] = pluralequation
+ store.updateheaderplural(nplurals, pluralequation)
+ # If we actually updated something significant, of course the file
+ # won't appear changed yet, which is probably what we want.
+ return int(nplurals)
+ elif isinstance(store, ts.tsfile):
+ return store.nplural()
+ else:
+ return 1
+
+class Document(gobject.GObject):
+ """Contains user state about a translate store which stores information like
+ GUI-toolkit-independent state (for example bookmarks) and index remappings
+ which are needed to"""
+
+ __gtype_name__ = "Document"
+
+ __gsignals__ = {
+ "cursor-changed": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ()),
+ }
+
+ def __init__(self, filename, store=None, mode_selector=None):
+ gobject.GObject.__init__(self)
+ if store:
+ self.store = store
+ else:
+ self.store = factory.getobject(filename)
+ if mode_selector is None:
+ mode_selector = ModeSelector(self)
+ else:
+ mode_selector.document = self
+ self.stats = statsdb.StatsCache().filestats(filename, checks.UnitChecker(), self.store)
+ self._correct_header()
+ self.nplurals = compute_nplurals(self.store)
+ self.mode = None
+ self.mode_cursor = None
+ self.mode_selector = mode_selector
+
+ self.set_mode(self.mode_selector.default_mode)
+ self.mode_selector.connect('mode-combo-changed', self._on_mode_combo_changed)
+
+ def _correct_header(self):
+ """This ensures that the file has a header if it is a poheader type of
+ file, and fixes the statistics if we had to add a header."""
+ if isinstance(self.store, poheader) and not self.store.header():
+ self.store.updateheader(add=True)
+ new_stats = {}
+ for key, values in self.stats.iteritems():
+ new_stats[key] = [value+1 for value in values]
+ self.stats = new_stats
+
+ def cursor_changed(self):
+ """Emits the "cursor-changed" event, no questions asked."""
+ self.emit('cursor-changed')
+
+ def refresh_cursor(self):
+ try:
+ old_cursor = self.mode_cursor
+ if self.mode_cursor != None:
+ self.mode_cursor = self.mode.cursor_from_element(self.mode_cursor.deref())
+ else:
+ self.mode_cursor = self.mode.cursor_from_element()
+
+ if self.mode_cursor.get_pos() < 0:
+ try:
+ self.mode_cursor.move(1)
+ except IndexError:
+ pass
+
+ if old_cursor and self.mode_cursor and old_cursor.get_pos() != self.mode_cursor.get_pos():
+ self.cursor_changed()
+
+ return True
+ except IndexError:
+ return False
+
+ def set_mode(self, mode):
+ logging.debug("Changing document mode to %s" % mode.mode_name)
+
+ self.mode_selector.set_mode(mode)
+ self.mode = mode
+
+ self.refresh_cursor()
+
+ def _on_mode_combo_changed(self, _mode_selector, mode):
+ self.set_mode(mode)
+
+ def get_source_language(self):
+ """Return the current document's source language."""
+ candidate = self.store.getsourcelanguage()
+ if candidate and not candidate in ['und', 'en', 'en_US']:
+ return candidate
+ else:
+ return pan_app.settings.language["sourcelang"]
+
+ def get_target_language(self):
+ """Return the current document's target language."""
+ candidate = self.store.gettargetlanguage()
+ if candidate and candidate != 'und':
+ return candidate
+ else:
+ return pan_app.settings.language["contentlang"]
Added: virtaal/branches/upstream/current/virtaal/formats.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/formats.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/formats.py (added)
+++ virtaal/branches/upstream/current/virtaal/formats.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,67 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+from os import path
+
+import gtk
+
+from translate.storage import factory
+import pan_app
+
+
+def file_open_chooser(_self, destroyCallback=None):
+ chooser = gtk.FileChooserDialog(
+ _('Choose a translation file'),
+ None,
+ gtk.FILE_CHOOSER_ACTION_OPEN,
+ (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)
+ )
+ if path.exists(pan_app.settings.general["lastdir"]):
+ chooser.set_current_folder(pan_app.settings.general["lastdir"])
+
+ chooser.set_default_response(gtk.RESPONSE_OK)
+
+ all_supported_filter = gtk.FileFilter()
+ all_supported_filter.set_name(_("All Supported Files"))
+ chooser.add_filter(all_supported_filter)
+ for name, extensions, mimetypes in factory.supported_files():
+ new_filter = gtk.FileFilter()
+ new_filter.set_name(name)
+ if extensions:
+ for extension in extensions:
+ new_filter.add_pattern("*." + extension)
+ all_supported_filter.add_pattern("*." + extension)
+ for compress_extension in factory.decompressclass.keys():
+ new_filter.add_pattern("*.%s.%s" % (extension, compress_extension))
+ all_supported_filter.add_pattern("*.%s.%s" % (extension, compress_extension))
+ if mimetypes:
+ for mimetype in mimetypes:
+ new_filter.add_mime_type(mimetype)
+ all_supported_filter.add_mime_type(mimetype)
+ chooser.add_filter(new_filter)
+ all_filter = gtk.FileFilter()
+ all_filter.set_name(_("All Files"))
+ all_filter.add_pattern("*")
+ chooser.add_filter(all_filter)
+
+ if destroyCallback:
+ chooser.connect("destroy", destroyCallback)
+
+ return chooser
Added: virtaal/branches/upstream/current/virtaal/main_window.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/main_window.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/main_window.py (added)
+++ virtaal/branches/upstream/current/virtaal/main_window.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,397 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+import os
+import os.path as path
+import time
+import traceback
+
+try:
+ import pygtk
+ pygtk.require("2.0")
+except:
+ pass
+
+import gobject
+import gtk
+from gtk import gdk
+from gtk import glade
+
+from translate.storage import poheader
+from support import openmailto
+
+import pan_app
+from widgets.entry_dialog import EntryDialog
+import store_grid
+import unit_renderer
+from about import About
+import formats
+import document
+import recent
+from support import bijection
+from autocompletor import AutoCompletor
+from autocorrector import AutoCorrector
+from mode_selector import ModeSelector
+
+# FIXME: Add docstrings!
+
+def load_glade_file(path_parts, domain):
+ gladename = pan_app.get_abs_data_filename(path_parts)
+ gui = glade.XML(gladename, domain=domain)
+ return gladename, gui
+
+
+class Virtaal:
+ """The entry point class for Virtaal"""
+
+ WRAP_DELAY = 0.25
+
+ def __init__(self, startup_file=None):
+ #Set the Glade file
+ self.gladefile, self.gui = load_glade_file(["virtaal", "virtaal.glade"], "virtaal")
+
+ #Create our events dictionary and connect it
+ dic = {
+ "on_mainwindow_destroy" : gtk.main_quit,
+ "on_mainwindow_delete" : self._on_mainwindow_delete,
+ "on_open_activate" : self._on_file_open,
+ "on_save_activate" : self._on_file_save,
+ "on_saveas_activate" : self._on_file_saveas,
+ "on_quit" : self._on_quit,
+ "on_about_activate" : self._on_help_about,
+ "on_localization_guide_activate" : self._on_localization_guide,
+ "on_menuitem_documentation_activate" : self._on_documentation,
+ "on_menuitem_report_bug_activate" : self._on_report_bug,
+ }
+ self.gui.signal_autoconnect(dic)
+
+ self.mode_bar = self.gui.get_widget("mode_bar")
+ self.status_bar = self.gui.get_widget("status_bar")
+ self.statusbar_context_id = self.status_bar.get_context_id("statusbar")
+ self.sw = self.gui.get_widget("scrolledwindow1")
+ self.main_window = self.gui.get_widget("MainWindow")
+ self.main_window.set_icon_from_file(pan_app.get_abs_data_filename(["icons", "virtaal.ico"]))
+ recent_files = self.gui.get_widget("recent_files")
+ recent.rc.connect("item-activated", self._on_recent_file_activated)
+ recent_files.set_submenu(recent.rc)
+ self._setup_key_bindings()
+ self.main_window.show()
+
+ self.modified = False
+ self.filename = None
+
+ self.store_grid = None
+ self.document = None
+
+ self.autocomp = AutoCompletor()
+ self.autocorr = AutoCorrector(acorpath=pan_app.get_abs_data_filename(['virtaal', 'autocorr']))
+
+ if startup_file != None:
+ self.load_file(startup_file)
+
+ def _setup_key_bindings(self):
+ self.accel_group = gtk.AccelGroup()
+ self.main_window.add_accel_group(self.accel_group)
+ gtk.accel_map_add_entry("<Virtaal>/Edit/Undo", gtk.keysyms.z, gdk.CONTROL_MASK)
+ gtk.accel_map_add_entry("<Virtaal>/Edit/Search", gtk.keysyms.F3, 0)
+ gtk.accel_map_add_entry("<Virtaal>/Navigation/Up", gtk.accelerator_parse("Up")[0], gdk.CONTROL_MASK)
+ gtk.accel_map_add_entry("<Virtaal>/Navigation/Down", gtk.accelerator_parse("Down")[0], gdk.CONTROL_MASK)
+ gtk.accel_map_add_entry("<Virtaal>/Navigation/PgUp", gtk.accelerator_parse("Page_Up")[0], gdk.CONTROL_MASK)
+ gtk.accel_map_add_entry("<Virtaal>/Navigation/PgDown", gtk.accelerator_parse("Page_Down")[0], gdk.CONTROL_MASK)
+ self.accel_group.connect_by_path("<Virtaal>/Edit/Undo", self._on_undo)
+ self.accel_group.connect_by_path("<Virtaal>/Edit/Search", self._on_search)
+
+ def _on_undo(self, _accel_group, acceleratable, _keyval, _modifier):
+ unit_renderer.undo(acceleratable.focus_widget)
+
+ def _on_search(self, _accel_group, acceleratable, _keyval, _modifier):
+ if not self.document:
+ return
+ self.document.mode_selector.select_mode_by_name('Search')
+ # FIXME: Hack to make sure that the search entry has focus after pressing F3:
+ self.document.mode_selector.current_mode.ent_search.grab_focus()
+
+ def _on_mainwindow_delete(self, _widget, _event):
+ return self._on_quit(_event)
+
+ def _on_quit(self, _event):
+ if self._confirm_unsaved(self.main_window):
+ return True
+ gtk.main_quit()
+ return False
+
+ def _on_file_open(self, _widget, destroyCallback=None):
+ chooser = formats.file_open_chooser(destroyCallback)
+ chooser.set_transient_for(self.main_window)
+ while True:
+ response = chooser.run()
+ if response == gtk.RESPONSE_OK:
+ filename = chooser.get_filename()
+ uri = chooser.get_uri()
+ pan_app.settings.general["lastdir"] = path.dirname(filename)
+ pan_app.settings.write()
+ if self.open_file(filename, chooser, uri=uri):
+ break
+ elif response == gtk.RESPONSE_CANCEL or \
+ response == gtk.RESPONSE_DELETE_EVENT:
+ break
+ chooser.destroy()
+
+ def _on_recent_file_activated(self, chooser):
+ item = chooser.get_current_item()
+ if item.exists():
+ # For now we only handle local files, and limited the recent
+ # manager to only give us those anyway, so we can get the filename
+ self.open_file(item.get_uri_display(), self.main_window, uri=item.get_uri())
+
+ def _confirm_unsaved(self, dialog):
+ if self.modified:
+ (RESPONSE_SAVE, RESPONSE_DISCARD) = (gtk.RESPONSE_YES, gtk.RESPONSE_NO)
+ dialog = gtk.MessageDialog(dialog,
+ gtk.DIALOG_MODAL,
+ gtk.MESSAGE_QUESTION,
+ gtk.BUTTONS_NONE,
+ _("The current file has been modified.\nDo you want to save your changes?"))
+ dialog.add_buttons(gtk.STOCK_SAVE, RESPONSE_SAVE)
+ dialog.add_buttons(_("_Discard"), RESPONSE_DISCARD)
+ dialog.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
+ dialog.set_default_response(RESPONSE_SAVE)
+ response = dialog.run()
+ dialog.destroy()
+ if response == RESPONSE_DISCARD:
+ return False
+ elif response in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
+ return True
+ elif response == RESPONSE_SAVE:
+ if self._on_file_save():
+ return True
+ return False
+
+ def open_file(self, filename, dialog, reload=False, uri=None):
+ if self._confirm_unsaved(dialog):
+ return True
+ if filename == self.filename and not reload:
+ dialog = gtk.MessageDialog(dialog,
+ gtk.DIALOG_MODAL,
+ gtk.MESSAGE_QUESTION,
+ gtk.BUTTONS_YES_NO,
+ _("You selected the currently open file for opening. Do you want to reload the file?"))
+ dialog.set_default_response(gtk.RESPONSE_NO)
+ response = dialog.run()
+ dialog.destroy()
+ if response in [gtk.RESPONSE_NO, gtk.RESPONSE_DELETE_EVENT]:
+ return True
+ return self.load_file(filename, dialog=dialog, uri=uri)
+
+ def load_file(self, filename, dialog=None, store=None, uri=None):
+ """Do the actual loading of the file into the GUI"""
+ if path.isfile(filename):
+ # To ensure that the WATCH cursor gets a chance to be displayed
+ # before we block the GUI, we need to add it to the idle
+ # processing
+ def hard_work(dialog=None):
+ try:
+ mode_selector = getattr(self.document, 'mode_selector', None)
+ self.document = document.Document(filename, store=store, mode_selector=mode_selector)
+ child = self.mode_bar.get_children()[0]
+ self.mode_bar.remove(child)
+ self.mode_bar.pack_start(self.document.mode_selector)
+ self.mode_bar.reorder_child(self.document.mode_selector, 0)
+
+ self.filename = filename
+ self.store_grid = store_grid.UnitGrid(self)
+ self.store_grid.connect("modified", self._on_modified)
+ child = self.sw.get_child()
+ self.sw.remove(child)
+ child.destroy()
+ self.sw.add(self.store_grid)
+ self.main_window.connect("configure-event", self.store_grid.on_configure_event)
+ self.main_window.show_all()
+ self.store_grid.grab_focus()
+ self._set_saveable(False)
+ menuitem = self.gui.get_widget("saveas_menuitem")
+ menuitem.set_sensitive(True)
+
+ self.autocomp.add_words_from_store(self.document.store)
+ self.autocorr.load_dictionary(lang=pan_app.settings.language['contentlang'])
+ self.store_grid.connect('cursor-changed', self._on_grid_cursor_changed)
+ if uri:
+ recent.rm.add_item(uri)
+ gobject.idle_add(self.main_window.window.set_cursor, None, priority=gobject.PRIORITY_LOW)
+
+ except Exception, e:
+ dialog = gtk.MessageDialog(dialog or self.main_window,
+ gtk.DIALOG_MODAL,
+ gtk.MESSAGE_ERROR,
+ gtk.BUTTONS_OK,
+ ("%s\n\n%s" % (_("Error opening file:"), str(e))))
+ self.main_window.window.set_cursor(None)
+ traceback.print_exc()
+ dialog.run()
+ dialog.destroy()
+ return False
+
+ self.main_window.window.set_cursor(gdk.Cursor(gdk.WATCH))
+ gobject.idle_add(hard_work, dialog)
+ return True
+
+ # File doesn't exist
+ dialog = gtk.MessageDialog(dialog or self.main_window,
+ gtk.DIALOG_MODAL,
+ gtk.MESSAGE_ERROR,
+ gtk.BUTTONS_OK,
+ _("%(filename)s does not exist." % {"filename": filename}))
+ self.main_window.window.set_cursor(None)
+ dialog.run()
+ dialog.destroy()
+ return False
+
+ def set_statusbar_message(self, msg):
+ self.status_bar.pop(self.statusbar_context_id)
+ self.status_bar.push(self.statusbar_context_id, msg)
+ if msg:
+ time.sleep(self.WRAP_DELAY)
+
+ def _set_saveable(self, value):
+ menuitem = self.gui.get_widget("save_menuitem")
+ menuitem.set_sensitive(value)
+ if self.filename:
+ modified = ""
+ if value:
+ modified = "*"
+ self.main_window.set_title((_('Virtaal - %(current_file)s %(modified_marker)s') % {"current_file": path.basename(self.filename), "modified_marker": modified}).rstrip())
+ self.modified = value
+
+ def _on_grid_cursor_changed(self, grid):
+ assert grid is self.store_grid
+
+ # Add words from previously handled widgets to the auto-completion list
+ for textview in self.autocomp.widgets:
+ buffer = textview.get_buffer()
+ bufftext = buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter()).decode('utf-8')
+ self.autocomp.add_words(self.autocomp.wordsep_re.split(bufftext))
+
+ self.autocomp.clear_widgets()
+ self.autocorr.clear_widgets()
+ for target in grid.renderer.get_editor(grid).targets:
+ self.autocomp.add_widget(target)
+ self.autocorr.add_widget(target)
+
+ # Let the mode selector know that about the cursor change so that it can
+ # perform any mode-specific actions needed.
+ self.document.mode_selector.cursor_changed(grid)
+
+ def _on_modified(self, _widget):
+ if not self.modified:
+ self._set_saveable(True)
+
+ def _on_file_save(self, _widget=None, filename=None):
+ if isinstance(self.document.store, poheader.poheader):
+ name = pan_app.settings.translator["name"]
+ email = pan_app.settings.translator["email"]
+ team = pan_app.settings.translator["team"]
+ if not name:
+ name = EntryDialog(_("Please enter your name"))
+ if name is None:
+ # User cancelled
+ return True
+ pan_app.settings.translator["name"] = name
+ if not email:
+ email = EntryDialog(_("Please enter your e-mail address"))
+ if email is None:
+ # User cancelled
+ return True
+ pan_app.settings.translator["email"] = email
+ if not team:
+ team = EntryDialog(_("Please enter your team's information"))
+ if team is None:
+ # User cancelled
+ return True
+ pan_app.settings.translator["team"] = team
+ pan_app.settings.write()
+ header_updates = {}
+ header_updates["PO_Revision_Date"] = time.strftime("%Y-%m-%d %H:%M") + poheader.tzstring()
+ header_updates["X_Generator"] = pan_app.x_generator
+ if name or email:
+ header_updates["Last_Translator"] = u"%s <%s>" % (name, email)
+ self.document.store.updatecontributor(name, email)
+ if team:
+ header_updates["Language-Team"] = team
+ self.document.store.updateheader(add=True, **header_updates)
+
+ try:
+ if filename is None or filename == self.filename:
+ self.document.store.save()
+ else:
+ self.filename = filename
+ self.document.store.savefile(filename)
+ self._set_saveable(False)
+ except IOError, e:
+ dialog = gtk.MessageDialog(self.main_window,
+ gtk.DIALOG_MODAL,
+ gtk.MESSAGE_ERROR,
+ gtk.BUTTONS_OK,
+ _("Could not save file.\n\n%(error_message)s\n\nTry saving at a different location." % {error_message: str(e)}))
+ dialog.set_title(_("Error"))
+ response = dialog.run()
+ dialog.destroy()
+
+ return False #continue normally
+
+ def _on_file_saveas(self, widget=None):
+ buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)
+ # TODO: use stock text for Save as..."
+ chooser = gtk.FileChooserDialog(
+ _("Save"),
+ self.main_window,
+ gtk.FILE_CHOOSER_ACTION_SAVE,
+ buttons
+ )
+ chooser.set_do_overwrite_confirmation(True)
+ directory, filename = path.split(self.filename)
+ chooser.set_current_name(filename)
+ chooser.set_default_response(gtk.RESPONSE_OK)
+ chooser.set_current_folder(directory)
+
+ response = chooser.run()
+ if response == gtk.RESPONSE_OK:
+ filename = chooser.get_filename()
+ self._on_file_save(widget, filename)
+ pan_app.settings.general["lastdir"] = path.dirname(filename)
+ pan_app.settings.write()
+ chooser.destroy()
+
+ def _on_help_about(self, _widget=None):
+ About(self.main_window)
+
+ def _on_localization_guide(self, _widget=None):
+ # Should be more redundent
+ # If the guide is installed and no internet then open local
+ # If Internet then go live, if no Internet or guide then disable
+ openmailto.open("http://translate.sourceforge.net/wiki/guide/start")
+
+ def _on_documentation(self, _widget=None):
+ openmailto.open("http://translate.sourceforge.net/wiki/virtaal/index")
+
+ def _on_report_bug(self, _widget=None):
+ openmailto.open("http://bugs.locamotion.org/enter_bug.cgi?product=Virtaal")
+
+ def run(self):
+ gtk.main()
Added: virtaal/branches/upstream/current/virtaal/markup.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/markup.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/markup.py (added)
+++ virtaal/branches/upstream/current/virtaal/markup.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,95 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2007-2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+import re
+
+
+xml_re = re.compile("<[^>]+>")
+
+def fancyspaces(string):
+ """Returns the fancy spaces that are easily visible."""
+ spaces = string.group()
+# while spaces[0] in "\t\n\r":
+# spaces = spaces[1:]
+ return '<span underline="low" foreground="grey"> </span>' * len(spaces)
+
+def markuptext(text, fancyspaces=False, markupescapes=True):
+ """Replace special characters &, <, >, add and handle escapes if asked for Pango."""
+ if not text:
+ return ""
+ text = text.replace("&", "&") # Must be done first!
+ text = text.replace("<", "<")
+ fancy_xml = lambda escape: \
+ '<span foreground="darkred">%s</span>' % escape.group()
+ text = xml_re.sub(fancy_xml, text)
+
+ if markupescapes:
+ fancyescape = lambda escape: \
+ '<span foreground="purple">%s</span>' % escape
+
+ text = text.replace("\r\n", fancyescape(r'\r\n') + '\n')
+ text = text.replace("\n", fancyescape(r'\n') + '\n')
+ text = text.replace("\r", fancyescape(r'\r') + '\n')
+ text = text.replace("\t", fancyescape(r'\t'))
+ # we don't need it at the end of the string
+ if text.endswith("\n"):
+ text = text[:-len("\n")]
+
+ if fancyspaces:
+ text = addfancyspaces(text)
+ return text
+
+def addfancyspaces(text):
+ """Insert fancy spaces"""
+ #More than two consecutive:
+ text = re.sub("[ ]{2,}", fancyspaces, text)
+ #At start of string
+ text = re.sub("^[ ]+", fancyspaces, text)
+ #After newline
+ text = re.sub("(?m)\n([ ]+)", fancyspaces, text)
+ #At end of string
+ text = re.sub("[ ]+$", fancyspaces, text)
+ return text
+
+def escape(text):
+ """This is to escape text for use with gtk.TextView"""
+ if not text:
+ return ""
+ text = text.replace("\\", '\\\\')
+ text = text.replace("\n", '\\n\n')
+ text = text.replace("\r", '\\r\n')
+ text = text.replace("\\r\n\\n",'\\r\\n')
+ text = text.replace("\t", '\\t')
+ if text.endswith("\n"):
+ text = text[:-len("\n")]
+ return text
+
+def unescape(text):
+ """This is to unescape text for use with gtk.TextView"""
+ if not text:
+ return ""
+ text = text.replace("\t", "")
+ text = text.replace("\n", "")
+ text = text.replace("\r", "")
+ text = text.replace("\\t", "\t")
+ text = text.replace("\\n", "\n")
+ text = text.replace("\\r", "\r")
+ text = text.replace("\\\\", "\\")
+ return text
Added: virtaal/branches/upstream/current/virtaal/mode_selector.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/mode_selector.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/mode_selector.py (added)
+++ virtaal/branches/upstream/current/virtaal/mode_selector.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,108 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+import gobject
+import gtk
+import logging
+
+import virtaal.modes
+
+
+class ModeSelector(gtk.HBox):
+ """A composite widget for selecting modes."""
+
+ __gtype_name__ = "ModeSelector"
+
+ __gsignals__ = {
+ "mode-combo-changed": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)),
+ }
+
+ DEFAULT_MODE_NAME = 'Default'
+
+ def __init__(self, document):
+ gtk.HBox.__init__(self)
+ self.document = document
+
+ # Add mode-selection combo box
+ self.cmb_modes = gtk.combo_box_new_text()
+ self.cmb_modes.connect('changed', self._on_cmbmode_change)
+ self.lbl_mode = gtk.Label()
+ self.lbl_mode.set_markup_with_mnemonic(_('_Mode: '))
+ self.lbl_mode.set_mnemonic_widget(self.cmb_modes)
+ self.pack_start(self.lbl_mode, expand=False)
+ self.pack_start(self.cmb_modes, expand=False)
+
+ self.mode_names = {} # mode_name to mode instance map
+ self.mode_index = {} # mode instance to index (in cmb_modes) map
+ i = 0
+ self.default_mode = None
+ self.current_mode = None
+
+ for mode in virtaal.modes.MODES.itervalues():
+ self.cmb_modes.append_text(mode.user_name)
+ self.mode_names[mode.user_name] = mode
+ self.mode_index[mode] = i
+ i += 1
+
+ if mode.mode_name == self.DEFAULT_MODE_NAME:
+ self.default_mode = mode
+
+ def cursor_changed(self, grid):
+ """Indirect handler for C{Virtaal.store_grid}'s "cursor-changed" event.
+
+ This method gets the C{UnitEditor} object for the newly selected
+ unit and passes it on to all modes' C{handle_unit()} methods. It
+ should only be called by a direct handler of the "cursor-changed"
+ event.
+
+ @type grid: UnitGrid
+ @param grid: The unit grid object that emitted the original signal.
+ """
+ self.current_mode.unit_changed(grid.renderer.get_editor(grid))
+
+ def select_mode_by_name(self, mode_name):
+ if mode_name in self.mode_names:
+ self.cmb_modes.set_active(self.mode_index[self.mode_names[mode_name]])
+ else:
+ raise ValueError('Unknown mode specified.')
+
+ def set_mode(self, mode):
+ # Remove previous mode's widgets
+ if self.cmb_modes.get_active() > -1:
+ for w in self.get_children():
+ if w is not self.cmb_modes and w is not self.lbl_mode:
+ self.remove(w)
+
+ # Select new mode and add its widgets
+ self.cmb_modes.set_active(self.mode_index[mode])
+ # The line above is needed to make sure that the combo is updated for direct calls to this method.
+ for w in mode.widgets:
+ if w.get_parent() is None:
+ self.pack_start(w, expand=False, padding=2)
+
+ self.show_all()
+ mode.selected(self.document)
+
+ if self.current_mode:
+ self.current_mode.unselected()
+ self.current_mode = mode
+
+ def _on_cmbmode_change(self, combo):
+ self.emit('mode-combo-changed', self.mode_names[combo.get_active_text()])
Added: virtaal/branches/upstream/current/virtaal/modes.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/modes.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/modes.py (added)
+++ virtaal/branches/upstream/current/virtaal/modes.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,123 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+from virtaal.support.set_enumerator import UnionSetEnumerator
+from virtaal.support.sorted_set import SortedSet
+
+
+class BidiIterator(object):
+ def __init__(self, itr):
+ self.itr = iter(itr)
+ self.hist = []
+ self.pos = -1
+
+ def next(self):
+ if self.pos < len(self.hist) - 1:
+ val = self.hist[self.pos]
+ self.pos += 1
+ return val
+ else:
+ self.hist.append(self.itr.next())
+ self.pos += 1
+ return self.hist[-1]
+
+ def prev(self):
+ if self.pos > -1:
+ val = self.hist[self.pos]
+ self.pos -= 1
+ return val
+ else:
+ raise StopIteration()
+
+ def __iter__(self):
+ return self
+
+
+class BaseMode(UnionSetEnumerator):
+ """Interface for other modes."""
+ mode_name = 'BaseMode'
+ user_name = '' # Sublcasses should mark this for translation with _()
+ widgets = []
+
+ def __init__(self):
+ raise NotImplementedError()
+
+ def selected(self, document):
+ """Signals that this mode has just been selected by the given document.
+ @type document: virtaal.document.Document
+ @param document: The document for which this mode was selected."""
+ raise NotImplementedError()
+
+ def unit_changed(self, editor):
+ """The selected unit has just changed.
+ @type editor: virtaal.unit_editor.UnitEditor
+ @param editor: The unit editor of the newly selected unit."""
+ raise NotImplementedError()
+
+ def unselected(self):
+ """Signals that this mode is unselected."""
+ raise NotImplementedError()
+
+
+class DefaultMode(BaseMode):
+ mode_name = "Default"
+ user_name = _("All")
+ widgets = []
+
+ def __init__(self):
+ UnionSetEnumerator.__init__(self)
+
+ def selected(self, document):
+ """This mode has just been selected, so we update this instance to match all units."""
+ UnionSetEnumerator.__init__(self, SortedSet(document.stats['total']))
+
+ def unit_changed(self, editor):
+ """This mode has nothing to do with selected units."""
+ pass
+
+ def unselected(self):
+ """This mode has nothing to do when unselected."""
+ pass
+
+
+class QuickTranslateMode(BaseMode):
+ mode_name = "Quick Translate"
+ user_name = _("Incomplete")
+ widgets = []
+
+ def __init__(self):
+ UnionSetEnumerator.__init__(self)
+
+ def selected(self, document):
+ """This mode has just been selected, so we update this instance to match all fuzzy/untranslated units."""
+ UnionSetEnumerator.__init__(self, SortedSet(document.stats['fuzzy']), SortedSet(document.stats['untranslated']))
+
+ def unit_changed(self, editor):
+ """This mode has nothing to do with selected units."""
+ pass
+
+ def unselected(self):
+ """This mode has nothing to do when unselected."""
+ pass
+
+
+from virtaal.search_mode import SearchMode
+
+MODES = dict( (klass.mode_name, klass()) for klass in globals().itervalues() if hasattr(klass, 'mode_name') and klass != BaseMode )
Added: virtaal/branches/upstream/current/virtaal/pan_app.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/pan_app.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/pan_app.py (added)
+++ virtaal/branches/upstream/current/virtaal/pan_app.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,159 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2007-2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+import logging
+
+try:
+ import iniparse as ConfigParser
+except ImportError, e:
+ import ConfigParser
+import os
+import sys
+import locale, gettext
+gettext.install("virtaal")
+
+from __version__ import ver
+
+
+x_generator = 'Virtaal ' + ver
+default_config = "~/.locamotion/virtaal.ini"
+
+def name():
+ # pwd is only available on UNIX
+ try:
+ import pwd
+ import getpass
+ except ImportError, _e:
+ return u""
+ return pwd.getpwnam(getpass.getuser())[4].split(",")[0]
+
+
+class Settings:
+ """Handles loading/saving settings from/to a configuration file."""
+
+ sections = ["translator", "general", "language", "undo"]
+
+ translator = {
+ "name": name(),
+ "email": "",
+ "team": "",
+ }
+ general = {
+ "lastdir": "",
+ "windowheight": 620,
+ "windowwidth": 400,
+ "terminology-dir": "",
+ }
+ language = {
+ "uilang": None,
+ "sourcelang": "en",
+ "contentlang": None,
+ "sourcefont": "mono 9",
+ "targetfont": "mono 9",
+ "nplurals": 0,
+ "plural": None,
+ }
+ undo = {
+ "depth": 50,
+ }
+
+ def __init__(self, filename = None):
+ """Load settings, using the given or default filename"""
+ if not filename:
+ self.filename = os.path.expanduser(default_config)
+ else:
+ self.filename = filename
+ if not os.path.isfile(self.filename):
+ raise Exception
+
+ try:
+ lang = locale.getdefaultlocale()[0]
+ self.language["uilang"] = lang
+ self.language["contentlang"] = lang
+ except:
+ logging.info("Could not get locale")
+ self.config = ConfigParser.ConfigParser()
+ self.read()
+
+ def read(self):
+ """Read the configuration file and set the dictionaries up."""
+ self.config.read(self.filename)
+ for section in self.sections:
+ if not self.config.has_section(section):
+ self.config.add_section(section)
+
+ for key, value in self.config.items("translator"):
+ self.translator[key] = value
+ for key, value in self.config.items("general"):
+ self.general[key] = value
+ for key, value in self.config.items("language"):
+ self.language[key] = value
+ for key, value in self.config.items("undo"):
+ self.undo[key] = value
+
+ def write(self):
+ """Write the configuration file."""
+ for key in self.translator:
+ self.config.set("translator", key, self.translator[key])
+ for key in self.general:
+ self.config.set("general", key, self.general[key])
+ for key in self.language:
+ self.config.set("language", key, self.language[key])
+ for key in self.undo:
+ self.config.set("undo", key, self.undo[key])
+
+ # make sure that the configuration directory exists
+ project_dir = os.path.split(self.filename)[0]
+ if not os.path.isdir(project_dir):
+ os.makedirs(project_dir)
+ file = open(self.filename, 'w')
+ self.config.write(file)
+ file.close()
+
+settings = Settings()
+
+
+def get_abs_data_filename(path_parts):
+ """Get the absolute path to the given file- or directory name in Virtaal's
+ data directory.
+
+ @type path_parts: list
+ @param path_parts: The path parts that can be joined by os.path.join().
+ """
+
+ if isinstance(path_parts, str):
+ path_parts = [path_parts]
+
+ BASE_DIRS = [
+ os.path.dirname(unicode(__file__, sys.getfilesystemencoding())),
+ os.path.dirname(unicode(sys.executable, sys.getfilesystemencoding()))
+ ]
+
+ DATA_DIRS = [
+ ["..", "share"],
+ ["share"]
+ ]
+
+ for basepath, data_dir in ((x, y) for x in BASE_DIRS for y in DATA_DIRS):
+ dir_and_filename = data_dir + path_parts
+ datafile = os.path.join(basepath or os.path.dirname(__file__), *dir_and_filename)
+ if os.path.exists(datafile):
+ return datafile
+ raise Exception('Could not find "%s"' % (os.path.join(*path_parts)))
Added: virtaal/branches/upstream/current/virtaal/recent.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/recent.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/recent.py (added)
+++ virtaal/branches/upstream/current/virtaal/recent.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,52 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+from translate.storage import factory
+
+import gtk
+
+
+rf = gtk.RecentFilter()
+for name, extensions, mimetypes in factory.supported_files():
+ if extensions:
+ for extension in extensions:
+ rf.add_pattern("*.%s" % extension)
+ for compress_extension in factory.decompressclass.keys():
+ rf.add_pattern("*.%s.%s" % (extension, compress_extension))
+ if mimetypes:
+ for mimetype in mimetypes:
+ rf.add_mime_type(mimetype)
+ rf.add_application("virtaal")
+ rf.add_application("poedit")
+ rf.add_application("kbabel")
+ rf.add_application("lokalize")
+ rf.add_application("gtranslator")
+
+rm = gtk.recent_manager_get_default()
+
+rc = gtk.RecentChooserMenu()
+# For now we don't handle non-local files yet
+rc.set_local_only(True)
+rc.set_show_not_found(False)
+rc.set_show_numbers(True)
+rc.set_show_tips(True)
+rc.set_sort_type(gtk.RECENT_SORT_MRU)
+rc.add_filter(rf)
+rc.set_limit(15)
Added: virtaal/branches/upstream/current/virtaal/rendering.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/rendering.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/rendering.py (added)
+++ virtaal/branches/upstream/current/virtaal/rendering.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,56 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+import gtk
+import pango
+
+import pan_app
+
+_font_descriptions = {}
+
+def get_font_description(description):
+ """Provide a pango.FontDescription and keep it for reuse."""
+ global _font_descriptions
+ if not description in _font_descriptions:
+ _font_descriptions[description] = pango.FontDescription(description)
+ return _font_descriptions[description]
+
+def get_source_font_description():
+ return get_font_description(pan_app.settings.language["sourcefont"])
+
+def get_target_font_description():
+ return get_font_description(pan_app.settings.language["targetfont"])
+
+
+_languages = {}
+
+def get_language(language):
+ """Provide a pango.Language and keep it for reuse."""
+ global _languages
+ if not language in _languages:
+ _languages[language] = pango.Language(language)
+ return _languages[language]
+
+def get_source_language():
+ return get_language(pan_app.settings.language["sourcelang"])
+
+def get_target_language():
+ return get_language(pan_app.settings.language["contentlang"])
+
Added: virtaal/branches/upstream/current/virtaal/search_mode.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/search_mode.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/search_mode.py (added)
+++ virtaal/branches/upstream/current/virtaal/search_mode.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,203 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+import gobject
+import gtk
+import logging
+import re
+
+from translate.tools.pogrep import GrepFilter
+
+from virtaal.modes import BaseMode
+from virtaal.support.set_enumerator import UnionSetEnumerator
+from virtaal.support.sorted_set import SortedSet
+
+
+HL_START, HL_END = range(2) # Indexes into SearchMode.highlight_marks
+
+class SearchMode(BaseMode):
+ mode_name = "Search"
+ user_name = _("Search")
+ widgets = []
+
+ highlight_marks = '[]'
+
+ SEARCH_DELAY = 500
+
+ def __init__(self):
+ UnionSetEnumerator.__init__(self)
+ self.ent_search = gtk.Entry()
+ self.ent_search.connect('changed', self._on_search_text_changed)
+ self.ent_search.connect('activate', self._on_entry_activate)
+ self.default_base = gtk.widget_get_default_style().base[gtk.STATE_NORMAL]
+ self.default_text = gtk.widget_get_default_style().text[gtk.STATE_NORMAL]
+ self.chk_casesensitive = gtk.CheckButton(_('_Case sensitive'))
+ self.chk_casesensitive.connect('toggled', self._refresh_proxy)
+ self.chk_regex = gtk.CheckButton(_("_Regular expression"))
+ self.chk_regex.connect('toggled', self._refresh_proxy)
+
+ self.prev_editor = None
+ self.re_search = None
+ self.widgets = [self.ent_search, self.chk_casesensitive, self.chk_regex]
+ self.filter = self.makefilter()
+ self.select_first_match = True
+ self._search_timeout = 0
+
+ def makefilter(self):
+ searchstring = self.ent_search.get_text()
+ searchparts = ('source', 'target')
+ ignorecase = not self.chk_casesensitive.get_active()
+ useregexp = self.chk_regex.get_active()
+
+ return GrepFilter(searchstring, searchparts, ignorecase, useregexp)
+
+ def selected(self, document):
+ """Focus the search entry.
+
+ This method should only be called after this mode has been selected."""
+ self.document = document
+ if not self.ent_search.get_text():
+ UnionSetEnumerator.__init__(self, SortedSet(document.stats['total']))
+ else:
+ self._on_search_text_changed(self.ent_search)
+
+ def grab_focus():
+ self.ent_search.grab_focus()
+ return False
+
+ # FIXME: The following line is a VERY UGLY HACK, but at least it works.
+ gobject.timeout_add(100, grab_focus)
+
+ def unit_changed(self, editor):
+ """Highlights all occurances of the search string in the newly selected unit."""
+ self._unhighlight_previous_matches()
+ if not self.ent_search.get_text():
+ return
+ self._highlight_matches(editor)
+ self.prev_editor = editor
+
+ def unselected(self):
+ """This mode has been unselected, so any current highlighting should be removed."""
+ self._unhighlight_previous_matches()
+
+ def update_search(self):
+ self.filter = self.makefilter()
+
+ # Filter stats with text in "self.ent_search"
+ filtered = []
+ i = 0
+ for unit in self.document.store.units:
+ if self.filter.filterunit(unit):
+ filtered.append(i)
+ i += 1
+
+ logging.debug('Search text: %s (%d matches)' % (self.ent_search.get_text(), len(filtered)))
+
+ old_elem = self.document.mode_cursor.deref()
+
+ if filtered:
+ self.ent_search.modify_base(gtk.STATE_NORMAL, self.default_base)
+ self.ent_search.modify_text(gtk.STATE_NORMAL, self.default_text)
+
+ searchstr = self.ent_search.get_text().decode('utf-8')
+ flags = re.UNICODE | re.MULTILINE
+ if not self.chk_casesensitive.get_active():
+ flags |= re.IGNORECASE
+ if not self.chk_regex.get_active():
+ searchstr = re.escape(searchstr)
+ self.re_search = re.compile(u'(%s)' % searchstr, flags)
+ UnionSetEnumerator.__init__(self, SortedSet(filtered))
+ else:
+ self.ent_search.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse('#f66'))
+ self.ent_search.modify_text(gtk.STATE_NORMAL, gtk.gdk.color_parse('#fff'))
+ self.re_search = None
+ # Act like the "Default" mode...
+ UnionSetEnumerator.__init__(self, SortedSet(self.document.stats['total']))
+
+ self.document.mode_cursor = self.document.mode.cursor_from_element(old_elem)
+ self.document.cursor_changed()
+
+ def grabfocus():
+ self.ent_search.grab_focus()
+ self.ent_search.set_position(-1)
+ return False
+ gobject.idle_add(grabfocus)
+
+ def _highlight_matches(self, editor):
+ if self.re_search is None:
+ return
+
+ for textview in editor.sources + editor.targets:
+ buff = textview.get_buffer()
+ buffstr = buff.get_text(buff.get_start_iter(), buff.get_end_iter()).decode('utf-8')
+
+ # First make sure that the current buffer contains a highlighting tag.
+ # Because a gtk.TextTag can only be associated with one gtk.TagTable,
+ # we make copies (created by _make_highlight_tag()) to add to all
+ # TagTables. If the tag is already added to a given table, a
+ # ValueError is raised which we can safely ignore.
+ try:
+ buff.get_tag_table().add(self._make_highlight_tag())
+ except ValueError:
+ pass
+
+ select_iters = []
+ for match in self.re_search.finditer(buffstr):
+ start_iter, end_iter = buff.get_iter_at_offset(match.start()), buff.get_iter_at_offset(match.end())
+ buff.apply_tag_by_name('highlight', start_iter, end_iter)
+
+ if textview in editor.targets and not select_iters and self.select_first_match:
+ select_iters = [start_iter, end_iter]
+
+ if select_iters:
+ def do_selection():
+ buff.move_mark_by_name('selection_bound', select_iters[0])
+ buff.move_mark_by_name('insert', select_iters[1])
+ return False
+ gobject.idle_add(do_selection)
+
+ def _unhighlight_previous_matches(self):
+ if self.prev_editor is None:
+ return
+
+ for textview in self.prev_editor.sources + self.prev_editor.targets:
+ buff = textview.get_buffer()
+ buff.remove_all_tags(buff.get_start_iter(), buff.get_end_iter())
+
+ def _make_highlight_tag(self):
+ tag = gtk.TextTag(name='highlight')
+ tag.set_property('background', 'blue')
+ tag.set_property('foreground', 'white')
+ return tag
+
+ def _on_entry_activate(self, entry):
+ if self.document is None:
+ return
+ self.document.cursor_changed()
+
+ def _on_search_text_changed(self, entry):
+ if self._search_timeout:
+ gobject.source_remove(self._search_timeout)
+ self._search_timeout = 0
+
+ self._search_timeout = gobject.timeout_add(self.SEARCH_DELAY, self.update_search)
+
+ def _refresh_proxy(self, *args):
+ self._on_search_text_changed(self.ent_search)
Added: virtaal/branches/upstream/current/virtaal/store_grid.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/store_grid.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/store_grid.py (added)
+++ virtaal/branches/upstream/current/virtaal/store_grid.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,214 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2007-2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+import logging
+
+import gtk
+import gobject
+
+from unit_renderer import UnitRenderer
+import store_model
+
+
+COLUMN_NOTE, COLUMN_UNIT, COLUMN_EDITABLE = 0, 1, 2
+
+def make_renderer(grid):
+ renderer = UnitRenderer(grid)
+ renderer.connect("editing-done", grid._on_cell_edited, grid.get_model())
+ renderer.connect("modified", grid._on_modified)
+ return renderer
+
+def make_column(renderer):
+ column = gtk.TreeViewColumn(None, renderer, unit=COLUMN_UNIT, editable=COLUMN_EDITABLE)
+ column.set_expand(True)
+ return column
+
+
+class UnitGrid(gtk.TreeView):
+ __gsignals__ = {
+ 'modified':(gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ())
+ }
+
+ def add_accelerator_bindings(self):
+ self.accel_group = gtk.AccelGroup()
+ self._owner.main_window.add_accel_group(self.accel_group)
+ self.accel_group.connect_by_path("<Virtaal>/Navigation/Up", self._move_up)
+ self.accel_group.connect_by_path("<Virtaal>/Navigation/Down", self._move_down)
+ self.accel_group.connect_by_path("<Virtaal>/Navigation/PgUp", self._move_pgup)
+ self.accel_group.connect_by_path("<Virtaal>/Navigation/PgDown", self._move_pgdown)
+
+ def enable_tooltips(self):
+ if hasattr(self, "set_tooltip_column"):
+ self.set_tooltip_column(COLUMN_NOTE)
+ self.set_rules_hint(True)
+
+ def install_callbacks(self):
+ self.connect('key-press-event', self._on_key_press)
+ self.connect("cursor-changed", self._on_cursor_changed)
+ self.connect("button-press-event", self._on_button_press)
+
+ def __init__(self, owner):
+ gtk.TreeView.__init__(self, store_model.UnitModel(owner.document.store, list(owner.document.mode_cursor)))
+
+ self._owner = owner
+ self.document = self._owner.document
+ self.set_headers_visible(False)
+ #self.set_direction(gtk.TEXT_DIR_LTR)
+
+ # TODO: Is this really necessary?
+ if len(self.get_model()) == 0:
+ raise ValueError(_("The file did not contain anything to translate."))
+
+ self.renderer = make_renderer(self)
+ self.append_column(make_column(self.renderer))
+ self.enable_tooltips()
+
+ self.document.connect("cursor-changed", self._on_document_cursor_changed)
+
+ self.install_callbacks()
+ self.add_accelerator_bindings()
+
+ gobject.idle_add(self._activate_editing_path,
+ self.get_model().store_index_to_path(self.document.mode_cursor.deref()))
+
+ # This must be changed to a mutex if you ever consider
+ # writing multi-threaded code. However, the motivation
+ # for this horrid little variable is so dubious that you'd
+ # be better off writing better code. I'm sorry to leave it
+ # to you.
+ self._waiting_for_row_change = 0
+
+ def _on_document_cursor_changed(self, _document):
+ # Select and edit the new row indicated by the new cursor position
+ path = self.get_model().store_index_to_path(self.document.mode_cursor.deref())
+ self._activate_editing_path(path)
+
+ def _activate_editing_path(self, new_path):
+ """Activates the given path for editing."""
+ # get the index of the translation unit in the translation store
+ #self.get_model().set(self.get_model().get_iter(new_path), COLUMN_EDITABLE, True)
+ self.get_model().set_editable(new_path)
+ def change_cursor():
+ self.set_cursor(new_path, self.get_columns()[0], start_editing=True)
+ self._waiting_for_row_change -= 1
+ self._waiting_for_row_change += 1
+ gobject.idle_add(change_cursor, priority=gobject.PRIORITY_DEFAULT_IDLE)
+
+ def _keyboard_move(self, offset):
+ # We don't want to process keyboard move events until we have finished updating
+ # the display after a move event. So we use this awful, awful, terrible scheme to
+ # keep track of pending draw events. In reality, it should be impossible for
+ # self._waiting_for_row_change to be larger than 1, but my superstition led me
+ # to be safe about it.
+ if self._waiting_for_row_change > 0:
+ return True
+
+ try:
+ self._owner.set_statusbar_message(self.document.mode_cursor.move(offset))
+ path = self.get_model().store_index_to_path(self.document.mode_cursor.deref())
+ self._activate_editing_path(path)
+ except IndexError:
+ pass
+
+ return True
+
+ def _move_up(self, _accel_group, _acceleratable, _keyval, _modifier):
+ return self._keyboard_move(-1)
+
+ def _move_down(self, _accel_group, _acceleratable, _keyval, _modifier):
+ return self._keyboard_move(1)
+
+ def _move_pgup(self, _accel_group, _acceleratable, _keyval, _modifier):
+ return self._keyboard_move(-10)
+
+ def _move_pgdown(self, _accel_group, _acceleratable, _keyval, _modifier):
+ return self._keyboard_move(10)
+
+ def _on_button_press(self, widget, event):
+ # If the event did not happen in the treeview, but in the
+ # editing widget, then the event window will not correspond to
+ # the treeview's drawing window. This happens when the
+ # user clicks on the edit widget. But if this happens, then
+ # we don't want anything to happen, so we return True.
+ if event.window != widget.get_bin_window():
+ return True
+ answer = self.get_path_at_pos(int(event.x), int(event.y))
+ if answer is None:
+ logging.debug("Not path found at (%d,%d)" % (int(event.x), int(event.y)))
+ return True
+ old_path, _old_column = self.get_cursor()
+ path, _column, _x, _y = answer
+ if old_path != path:
+ index = self.get_model().path_to_store_index(path)
+ if index not in self.document.mode:
+ logging.debug("Falling to default")
+ from virtaal.modes import MODES
+ self.document.set_mode(MODES['Default']) # FIXME: This module should not need to import modes
+
+ self.document.mode_cursor = self.document.mode.cursor_from_element(index)
+ self._activate_editing_path(path)
+ return True
+
+ def on_configure_event(self, _event, *_user_args):
+ path, column = self.get_cursor()
+
+ # Horrible hack.
+ # We use set_cursor to cause the editable area to be recreated so that
+ # it can be drawn correctly. This has to be delayed (we used idle_add),
+ # since calling it immediately after columns_autosize() does not work.
+ def reset_cursor():
+ if path != None:
+ self.set_cursor(path, column, start_editing=True)
+ return False
+
+ self.columns_autosize()
+ gobject.idle_add(reset_cursor)
+
+ return False
+
+ def _on_modified(self, _widget):
+ self.emit("modified")
+ return True
+
+ def _on_cell_edited(self, _cell, _path_string, must_advance, _modified, _model):
+ if must_advance:
+ return self._keyboard_move(1)
+ return True
+
+ def _on_cursor_changed(self, _treeview):
+ path, _column = self.get_cursor()
+
+ # We defer the scrolling until GTK has finished all its current drawing
+ # tasks, hence the gobject.idle_add. If we don't wait, then the TreeView
+ # draws the editor widget in the wrong position. Presumably GTK issues
+ # a redraw event for the editor widget at a given x-y position and then also
+ # issues a TreeView scroll; thus, the editor widget gets drawn at the wrong
+ # position.
+ def do_scroll():
+ self.scroll_to_cell(path, self.get_column(0), True, 0.5, 0.0)
+ return False
+
+ gobject.idle_add(do_scroll)
+ return True
+
+ def _on_key_press(self, _widget, _event, _data=None):
+ # The TreeView does interesting things with combos like SHIFT+TAB.
+ # So we're going to stop it from doing this.
+ return True
Added: virtaal/branches/upstream/current/virtaal/store_model.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/store_model.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/store_model.py (added)
+++ virtaal/branches/upstream/current/virtaal/store_model.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,114 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+__all__ = ['UnitModel']
+
+from bisect import bisect_left
+
+import gobject
+import gtk
+
+from markup import markuptext
+
+
+class UnitModel(gtk.GenericTreeModel):
+ def __init__(self, store, editable_indices):
+ gtk.GenericTreeModel.__init__(self)
+ self._store = store
+ self._editable_indices = editable_indices
+ self._current_editable = 0
+
+ def on_get_flags(self):
+ return gtk.TREE_MODEL_ITERS_PERSIST | gtk.TREE_MODEL_LIST_ONLY
+
+ def on_get_n_columns(self):
+ return 3
+
+ def on_get_column_type(self, index):
+ if index == 0:
+ return gobject.TYPE_STRING
+ elif index == 1:
+ return gobject.TYPE_PYOBJECT
+ else:
+ return gobject.TYPE_BOOLEAN
+
+ def on_get_iter(self, path):
+ return path[0]
+
+ def on_get_path(self, rowref):
+ return (rowref,)
+
+ def on_get_value(self, rowref, column):
+ if column <= 1:
+ unit = self._store.units[self._editable_indices[rowref]]
+ if column == 0:
+ return markuptext(unit.getnotes(), markupescapes=False) or None
+ else:
+ return unit
+ else:
+ return self._current_editable == rowref
+
+ def on_iter_next(self, rowref):
+ if rowref < len(self._editable_indices) - 1:
+ return rowref + 1
+ else:
+ return None
+
+ def on_iter_children(self, parent):
+ if parent == None and len(self._editable_indices) > 0:
+ return 0
+ else:
+ return None
+
+ def on_iter_has_child(self, rowref):
+ return False
+
+ def on_iter_n_children(self, rowref):
+ if rowref == None:
+ return len(self._editable_indices)
+ else:
+ return 0
+
+ def on_iter_nth_child(self, parent, n):
+ if parent == None:
+ return n
+ else:
+ return None
+
+ def on_iter_parent(self, child):
+ return None
+
+ # Non-model-interface methods
+
+ def set_editable(self, new_path):
+ old_path = (self._current_editable,)
+ self._current_editable = new_path[0]
+ self.row_changed(old_path, self.get_iter(old_path))
+ self.row_changed(new_path, self.get_iter(new_path))
+
+ def store_index_to_path(self, store_index):
+ itr = bisect_left(self._editable_indices, store_index)
+ if self._editable_indices[itr] == store_index:
+ return self.on_get_path(itr)
+ else:
+ raise IndexError()
+
+ def path_to_store_index(self, path):
+ return self._editable_indices[path[0]]
Added: virtaal/branches/upstream/current/virtaal/support/__init__.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/support/__init__.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/support/__init__.py (added)
+++ virtaal/branches/upstream/current/virtaal/support/__init__.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,19 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
Added: virtaal/branches/upstream/current/virtaal/support/bijection.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/support/bijection.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/support/bijection.py (added)
+++ virtaal/branches/upstream/current/virtaal/support/bijection.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,30 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+from UserDict import UserDict
+
+
+class Bijection(UserDict):
+ def __init__(self, iterable):
+ UserDict.__init__(self)
+ self.inverse = {}
+ for key, val in iterable:
+ self[key] = val
+ self.inverse[val] = key
Added: virtaal/branches/upstream/current/virtaal/support/memoize.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/support/memoize.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/support/memoize.py (added)
+++ virtaal/branches/upstream/current/virtaal/support/memoize.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,64 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+__all__ = ['memoize', 'invalidates_memoization']
+
+memoize_table = {}
+
+def get_full_fn_name(f):
+ return "%s.%s" % (f.__module__, f.__name__)
+
+def memoize(f):
+ """A general memoization decorator.
+
+ Use it as follows::
+ @memoize
+ my_function(a, b, c):
+ ...
+ """
+ memoize_dict = {}
+ memoize_table[get_full_fn_name(f)] = memoize_dict
+ def memoized_f(*args, **kw_args):
+ lookup_key = (args, tuple(kw_args.iteritems()))
+ if lookup_key in memoize_dict:
+ return memoize_dict[lookup_key]
+ else:
+ memoize_dict[lookup_key] = f(*args, **kw_args)
+ return memoize_dict[lookup_key]
+ memoized_f._original_f = f
+ return memoized_f
+
+def get_real_fn(f):
+ """Peel away any memoization layers from around a function
+ and return the unmemoized function."""
+ if hasattr(f, '_original_f'):
+ return get_real_fn(f._original_f)
+ else:
+ return f
+
+def invalidates_memoization(*functions):
+ def invalid_applicator(f):
+ function_names = [get_full_fn_name(get_real_fn(fn)) for fn in functions]
+ def invalidating_f(*args, **kw_args):
+ for function_name in function_names:
+ memoize_table[function_name].clear()
+ return f(*args, **kw_args)
+ return invalidating_f
+ return invalid_applicator
Added: virtaal/branches/upstream/current/virtaal/support/openmailto.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/support/openmailto.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/support/openmailto.py (added)
+++ virtaal/branches/upstream/current/virtaal/support/openmailto.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,362 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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.
+#
+# This file incorporates work covered by the following copyright:
+#
+# Copyright (c) 2007, Antonio Valentino
+# Obtained from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/511443
+# which is licensed under the Python license.
+
+"""Utilities for opening files or URLs in the registered default application
+and for sending e-mail using the user's preferred composer."""
+
+__version__ = '1.0'
+__all__ = ['open', 'mailto']
+
+import os
+import sys
+import webbrowser
+import subprocess
+
+from email.Utils import encode_rfc2231
+
+
+_controllers = {}
+_open = None
+
+
+class BaseController(object):
+ '''Base class for open program controllers.'''
+
+ def __init__(self, name):
+ self.name = name
+
+ def open(self, filename):
+ raise NotImplementedError
+
+
+class Controller(BaseController):
+ '''Controller for a generic open program.'''
+
+ def __init__(self, *args):
+ super(Controller, self).__init__(os.path.basename(args[0]))
+ self.args = list(args)
+
+ def _invoke(self, cmdline):
+ if sys.platform[:3] == 'win':
+ closefds = False
+ startupinfo = subprocess.STARTUPINFO()
+ startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
+ else:
+ closefds = True
+ startupinfo = None
+
+ if (os.environ.get('DISPLAY') or sys.platform[:3] == 'win' or
+ sys.platform == 'darwin'):
+ inout = file(os.devnull, 'r+')
+ else:
+ # for TTY programs, we need stdin/out
+ inout = None
+
+ # if possible, put the child precess in separate process group,
+ # so keyboard interrupts don't affect child precess as well as
+ # Python
+ setsid = getattr(os, 'setsid', None)
+ if not setsid:
+ setsid = getattr(os, 'setpgrp', None)
+
+ pipe = subprocess.Popen(cmdline, stdin=inout, stdout=inout,
+ stderr=inout, close_fds=closefds,
+ preexec_fn=setsid, startupinfo=startupinfo)
+
+ # It is assumed that this kind of tools (gnome-open, kfmclient,
+ # exo-open, xdg-open and open for OSX) immediately exit after lauching
+ # the specific application
+ returncode = pipe.wait()
+ if hasattr(self, 'fixreturncode'):
+ returncode = self.fixreturncode(returncode)
+ return not returncode
+
+ def open(self, filename):
+ if isinstance(filename, basestring):
+ cmdline = self.args + [filename]
+ else:
+ # assume it is a sequence
+ cmdline = self.args + filename
+ try:
+ return self._invoke(cmdline)
+ except OSError:
+ return False
+
+
+# Platform support for Windows
+if sys.platform[:3] == 'win':
+
+ class Start(BaseController):
+ '''Controller for the win32 start progam through os.startfile.'''
+
+ def open(self, filename):
+ try:
+ os.startfile(filename)
+ except WindowsError:
+ # [Error 22] No application is associated with the specified
+ # file for this operation: '<URL>'
+ return False
+ else:
+ return True
+
+ _controllers['windows-default'] = Start("start")
+ _open = _controllers['windows-default'].open
+
+
+# Platform support for MacOS
+elif sys.platform == 'darwin':
+ _controllers['open']= Controller('open')
+ _open = _controllers['open'].open
+
+
+# Platform support for Unix
+else:
+
+ import commands
+
+ # @WARNING: use the private API of the webbrowser module
+ from webbrowser import _iscommand
+
+ class KfmClient(Controller):
+ '''Controller for the KDE kfmclient program.'''
+
+ def __init__(self, kfmclient='kfmclient'):
+ super(KfmClient, self).__init__(kfmclient, 'exec')
+ self.kde_version = self.detect_kde_version()
+
+ def detect_kde_version(self):
+ kde_version = None
+ try:
+ info = commands.getoutput('kde-config --version')
+
+ for line in info.splitlines():
+ if line.startswith('KDE'):
+ kde_version = line.split(':')[-1].strip()
+ break
+ except (OSError, RuntimeError):
+ pass
+
+ return kde_version
+
+ def fixreturncode(self, returncode):
+ if returncode is not None and self.kde_version > '3.5.4':
+ return returncode
+ else:
+ return os.EX_OK
+
+ def detect_desktop_environment():
+ '''Checks for known desktop environments
+
+ Return the desktop environments name, lowercase (kde, gnome, xfce)
+ or "generic"
+
+ '''
+
+ desktop_environment = 'generic'
+
+ if os.environ.get('KDE_FULL_SESSION') == 'true':
+ desktop_environment = 'kde'
+ elif os.environ.get('GNOME_DESKTOP_SESSION_ID'):
+ desktop_environment = 'gnome'
+ else:
+ try:
+ info = commands.getoutput('xprop -root _DT_SAVE_MODE')
+ if ' = "xfce4"' in info:
+ desktop_environment = 'xfce'
+ except (OSError, RuntimeError):
+ pass
+
+ return desktop_environment
+
+
+ def register_X_controllers():
+ if _iscommand('kfmclient'):
+ _controllers['kde-open'] = KfmClient()
+
+ for command in ('gnome-open', 'exo-open', 'xdg-open'):
+ if _iscommand(command):
+ _controllers[command] = Controller(command)
+
+ def get():
+ controllers_map = { \
+ 'gnome': 'gnome-open',
+ 'kde': 'kde-open',
+ 'xfce': 'exo-open',
+ }
+
+ desktop_environment = detect_desktop_environment()
+
+ try:
+ controller_name = controllers_map[desktop_environment]
+ return _controllers[controller_name].open
+
+ except KeyError:
+ if _controllers.has_key('xdg-open'):
+ return _controllers['xdg-open'].open
+ else:
+ return webbrowser.open
+
+
+ if os.environ.get("DISPLAY"):
+ register_X_controllers()
+ _open = get()
+
+
+def open(filename):
+ '''Open a file or an URL in the registered default application.'''
+
+ return _open(filename)
+
+
+def _fix_addersses(**kwargs):
+ for headername in ('address', 'to', 'cc', 'bcc'):
+ try:
+ headervalue = kwargs[headername]
+ if not headervalue:
+ del kwargs[headername]
+ continue
+ elif not isinstance(headervalue, basestring):
+ # assume it is a sequence
+ headervalue = ','.join(headervalue)
+
+ except KeyError:
+ pass
+ except TypeError:
+ raise TypeError('string or sequence expected for "%s", ' \
+ '%s found' % (headername,
+ type(headervalue).__name__))
+ else:
+ translation_map = {'%': '%25', '&': '%26', '?': '%3F'}
+ for char, replacement in translation_map.items():
+ headervalue = headervalue.replace(char, replacement)
+ kwargs[headername] = headervalue
+
+ return kwargs
+
+
+def mailto_format(**kwargs):
+ # @TODO: implement utf8 option
+
+ kwargs = _fix_addersses(**kwargs)
+ parts = []
+ for headername in ('to', 'cc', 'bcc', 'subject', 'body', 'attach'):
+ if kwargs.has_key(headername):
+ headervalue = kwargs[headername]
+ if not headervalue:
+ continue
+ if headername in ('address', 'to', 'cc', 'bcc'):
+ parts.append('%s=%s' % (headername, headervalue))
+ else:
+ headervalue = encode_rfc2231(headervalue) # @TODO: check
+ parts.append('%s=%s' % (headername, headervalue))
+
+ mailto_string = 'mailto:%s' % kwargs.get('address', '')
+ if parts:
+ mailto_string = '%s?%s' % (mailto_string, '&'.join(parts))
+
+ return mailto_string
+
+
+def mailto(address, to=None, cc=None, bcc=None, subject=None, body=None,
+ attach=None):
+ '''Send an e-mail using the user's preferred composer.
+
+ Open the user's preferred e-mail composer in order to send a mail to
+ address(es) that must follow the syntax of RFC822. Multiple addresses
+ may be provided (for address, cc and bcc parameters) as separate
+ arguments.
+
+ All parameters provided are used to prefill corresponding fields in
+ the user's e-mail composer. The user will have the opportunity to
+ change any of this information before actually sending the e-mail.
+
+ @param address: destination recipient
+ @param cc: recipient to be copied on the e-mail
+ @param bcc: recipient to be blindly copied on the e-mail
+ @param subject: subject for the e-mail
+ @param body: body of the e-mail. Since the user will be able
+ to make changes before actually sending the e-mail, this
+ can be used to provide the user with a template for the
+ e-mail text may contain linebreaks
+ @param attach: an attachment for the e-mail. file must point to
+ an existing file
+
+ '''
+
+ mailto_string = mailto_format(**locals())
+ return open(mailto_string)
+
+
+if __name__ == '__main__':
+ from optparse import OptionParser
+
+ version = '%%prog %s' % __version__
+ usage = (
+ '\n\n%prog FILENAME [FILENAME(s)] -- for opening files'
+ '\n\n%prog -m [OPTIONS] ADDRESS [ADDRESS(es)] -- for sending e-mails'
+ )
+
+ parser = OptionParser(usage=usage, version=version, description=__doc__)
+ parser.add_option('-m', '--mailto', dest='mailto_mode', default=False, \
+ action='store_true', help='set mailto mode. '
+ 'If not set any other option is ignored')
+ parser.add_option('--cc', dest='cc', help='specify a recipient to be '
+ 'copied on the e-mail')
+ parser.add_option('--bcc', dest='bcc', help='specify a recipient to be '
+ 'blindly copied on the e-mail')
+ parser.add_option('--subject', dest='subject',
+ help='specify a subject for the e-mail')
+ parser.add_option('--body', dest='body', help='specify a body for the '
+ 'e-mail. Since the user will be able to make changes '
+ 'before actually sending the e-mail, this can be used '
+ 'to provide the user with a template for the e-mail '
+ 'text may contain linebreaks')
+ parser.add_option('--attach', dest='attach', help='specify an attachment '
+ 'for the e-mail. file must point to an existing file')
+
+ (options, args) = parser.parse_args()
+
+ if not args:
+ parser.print_usage()
+ parser.exit(1)
+
+ if options.mailto_mode:
+ if not mailto(args, None, options.cc, options.bcc, options.subject,
+ options.body, options.attach):
+ sys.exit('Unable to open the e-mail client')
+ else:
+ for name in ('cc', 'bcc', 'subject', 'body', 'attach'):
+ if getattr(options, name):
+ parser.error('The "cc", "bcc", "subject", "body" and "attach" '
+ 'options are only accepten in mailto mode')
+ success = False
+ for arg in args:
+ if not open(arg):
+ print 'Unable to open "%s"' % arg
+ else:
+ success = True
+ sys.exit(success)
Added: virtaal/branches/upstream/current/virtaal/support/partial.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/support/partial.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/support/partial.py (added)
+++ virtaal/branches/upstream/current/virtaal/support/partial.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,122 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+__all__ = ['partial', 'compose', 'post']
+
+
+def copy_attrs(source_func, target_func):
+ for attr in ('__module__', '__name__', '__doc__'):
+ setattr(target_func, attr, getattr(source_func, attr))
+ for attr in ('__dict__',):
+ getattr(target_func, attr).update(getattr(source_func, attr, {}))
+
+def partial(f, *args, **kwargs):
+ """Given a function foo, return a new function bar with some parameters already specified.
+
+ This can best be illustrated by an example:
+
+ >>> def foo(a, b):
+ ... return a - b
+ ...
+ ... bar = partial(foo, b=2)
+ ... bar(1)
+ -1
+
+ Partial application is more powerful than Python lambda functions, since the latter
+ does not store a copy to its environment; thus if you reference a variable i in a
+ lambda and i changes, then the lambda will also see a changed copy.
+ """
+ def new_f(*new_args, **new_kwargs):
+ all_args = args + new_args
+ kwargs.update(new_kwargs)
+ return f(*all_args, **kwargs)
+
+ copy_attrs(f, new_f)
+ return new_f
+
+def compose(*funcs):
+ """Compose two or more functions into a single function.
+
+ This operates as mathematical composition. Thus, C{compose(a, b, c)}
+ is equivalent to M{a . b . c} in mathematical notation. In Python,
+ this can also be written as C{lambda *args: a(b(c(*args)))}.
+ """
+ def new_f(args):
+ return reduce(lambda args, f: f(args), reversed(funcs), args)
+
+ # If we compose a, b and c, we make the name of the composed function
+ # "a.b.c"
+ setattr(new_f, '__name__', ".".join(f.__name__ for f in funcs))
+ # Create a module name of the form a.__module__:b.__module__:c.__module__
+ # TODO: Check whether such a module name will cause trouble
+ setattr(new_f, '__module__', ":".join(f.__module__ for f in funcs))
+ setattr(new_f, '__doc__', "composition")
+
+ return new_f
+
+def post(post_f):
+ """Turn a normal Python function into a decorator which causes the code in
+ the function to be executed after the code in the decorated function is
+ executed.
+
+ For example, suppose that you have a function foo. If you want the code in
+ bar to be executed after the code in foo, you can decorate foo as follows::
+
+ @post(bar)
+ def foo(a, b, c, ...)
+
+ The function bar needs to have a signature as follows::
+ def bar(foo_return_value, a, b, c, ...)
+
+ Thus, the first parameter of bar is the return value of foo and the rest of
+ its parameters are identical to that of foo (this is so that bar has access to
+ the parameters.
+
+ As a concrete example, an implementation of bar might look something like::
+ def bar(foo_return, a, *args):
+ print 'The return value of the function that ran before me is %s' % repr(foo_return)
+ print 'The first parameter is %s'% repr(a)
+
+ return foo_return + 42
+
+ and the definition of foo something like::
+ @post(bar)
+ def foo(a, b, c):
+ print 'I am foo'
+ return 0
+
+ Thus::
+ >>> foo(1, 2, 3)
+ ... I am foo
+ ... The return value of the function that ran before me is 0
+ ... The first parameter is 1
+ ... 42
+ """
+ def decorator(f):
+ def new_f(*args, **kwargs):
+ return post_f(f(*args, **kwargs), *args, **kwargs)
+
+ copy_attrs(f, new_f)
+ setattr(new_f, '__name__', f.__name__ + "+" + post_f.__name__)
+ setattr(new_f, '__module__', f.__module__ + "+" + post_f.__module__)
+ return new_f
+
+ copy_attrs(post_f, decorator)
+ return decorator
Added: virtaal/branches/upstream/current/virtaal/support/set_enumerator.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/support/set_enumerator.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/support/set_enumerator.py (added)
+++ virtaal/branches/upstream/current/virtaal/support/set_enumerator.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,138 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2007-2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+import gobject
+from bisect import bisect_left
+
+from virtaal.support.sorted_set import SortedSet
+
+
+# FIXME: Add docstrings!
+
+class Cursor(gobject.GObject):
+ __gtype_name__ = "Cursor"
+
+ def __init__(self, union_set, pos=-1):
+ gobject.GObject.__init__(self)
+ if pos >= len(union_set):
+ # TODO: Push new status message: 'End of page reached, continuing at the top'
+ pos = 0
+ self.union_set = union_set
+ self.union_set.connect('add', self._on_add)
+ self.union_set.connect('remove', self._on_remove)
+ self._pos = pos
+
+ def _on_add(self, _src, cursor_pos, _element):
+ if self._pos >= cursor_pos:
+ self._pos += 1
+
+ def _on_remove(self, _src, cursor_pos, _element):
+ if self._pos >= cursor_pos:
+ self._pos -= 1
+
+ def _assert_valid_index(self, index):
+ if not 0 <= index < len(self.union_set):
+ raise IndexError()
+
+ def move(self, offset):
+ newpos = self._pos + offset
+ statusmsg = ''
+ try:
+ self._assert_valid_index(newpos)
+ except IndexError:
+ if newpos < 0:
+ newpos += len(self.union_set)
+ statusmsg = _('Top of page reached, continuing at the bottom')
+ else:
+ # If we get here, newpos > len(self.union_set.set.data)
+ newpos -= len(self.union_set.set.data)
+ statusmsg = _('End of page reached, continuing at the top')
+ self._pos = newpos
+ return statusmsg
+
+ def deref(self, index=None):
+ if index == None:
+ index = self._pos
+ self._assert_valid_index(index)
+ return self.union_set.set.data[index]
+
+ def get_pos(self):
+ return self._pos
+
+ def __iter__(self):
+ def iterator():
+ for element in self.union_set.set.data:
+ yield element
+
+ return iterator()
+
+
+class UnionSetEnumerator(gobject.GObject):
+ __gtype_name__ = "UnionSetEnumerator"
+
+ __gsignals__ = {
+ "remove": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_INT, gobject.TYPE_PYOBJECT)),
+ "add": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_INT, gobject.TYPE_PYOBJECT))
+ }
+
+ def __init__(self, *sets):
+ gobject.GObject.__init__(self)
+
+ if len(sets) > 0:
+ self.sets = sets
+ self.set = reduce(lambda big_set, set: big_set.union(set), sets[1:], sets[0])
+ for set_ in self.sets:
+ set_.connect('before-add', self._before_add)
+ set_.connect('before-remove', self._before_remove)
+ else:
+ self.sets = [SortedSet([])]
+ self.set = SortedSet([])
+
+ #cursor = property(lambda self: self._current_element, _set_cursor)
+
+ def __len__(self):
+ return len(self.set.data)
+
+ def __contains__(self, element):
+ try:
+ return element in self.set
+ except IndexError:
+ return False
+
+ def _before_add(self, _src, _pos, element):
+ if element not in self.set:
+ self.set.add(element)
+ cursor_pos = bisect_left(self.set.data, element)
+ self.emit('add', self, cursor_pos, element)
+
+ def _before_remove(self, _src, _pos, element):
+ if element in self.set:
+ self.set.remove(element)
+ self.emit('remove', self, bisect_left(self.set.data, element), element)
+
+ def cursor_from_element(self, element=None):
+ if element != None:
+ return Cursor(self, bisect_left(self.set.data, element))
+ else:
+ return Cursor(self)
+
+ def remove(self, element):
+ for set_ in self.sets:
+ set_.remove(element)
Added: virtaal/branches/upstream/current/virtaal/support/simplegeneric.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/support/simplegeneric.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/support/simplegeneric.py (added)
+++ virtaal/branches/upstream/current/virtaal/support/simplegeneric.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,102 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+# This file was originally part of the PEAK project:
+# http://peak.telecommunity.com/DevCenter/FrontPage
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+__all__ = ["generic"]
+
+from types import ClassType, InstanceType
+classtypes = type, ClassType
+
+
+def generic(func):
+ """Create a simple generic function"""
+
+ _sentinel = object()
+
+ def _by_class(*args, **kw):
+ cls = args[0].__class__
+ for t in type(cls.__name__, (cls,object), {}).__mro__:
+ f = _gbt(t, _sentinel)
+ if f is not _sentinel:
+ return f(*args, **kw)
+ else:
+ return func(*args, **kw)
+
+ _by_type = {object: func, InstanceType: _by_class}
+ _gbt = _by_type.get
+
+ def when_type(t):
+ """Decorator to add a method that will be called for type `t`"""
+ if not isinstance(t, classtypes):
+ raise TypeError(
+ "%r is not a type or class" % (t,)
+ )
+ def decorate(f):
+ if _by_type.setdefault(t,f) is not f:
+ raise TypeError(
+ "%r already has method for type %r" % (func, t)
+ )
+ return f
+ return decorate
+
+ _by_object = {}
+ _gbo = _by_object.get
+
+ def when_object(o):
+ """Decorator to add a method that will be called for object `o`"""
+ def decorate(f):
+ if _by_object.setdefault(id(o), (o,f))[1] is not f:
+ raise TypeError(
+ "%r already has method for object %r" % (func, o)
+ )
+ return f
+ return decorate
+
+ def dispatch(*args, **kw):
+ f = _gbo(id(args[0]), _sentinel)
+ if f is _sentinel:
+ for t in type(args[0]).__mro__:
+ f = _gbt(t, _sentinel)
+ if f is not _sentinel:
+ return f(*args, **kw)
+ else:
+ return func(*args, **kw)
+ else:
+ return f[1](*args, **kw)
+
+ dispatch.__name__ = func.__name__
+ dispatch.__dict__ = func.__dict__.copy()
+ dispatch.__doc__ = func.__doc__
+ dispatch.__module__ = func.__module__
+
+ dispatch.when_type = when_type
+ dispatch.when_object = when_object
+ dispatch.default = func
+ dispatch.has_object = lambda o: id(o) in _by_object
+ dispatch.has_type = lambda t: t in _by_type
+ return dispatch
+
+def test_suite():
+ import doctest
+ return doctest.DocFileSuite(
+ 'README.txt',
+ optionflags=doctest.ELLIPSIS|doctest.REPORT_ONLY_FIRST_FAILURE,
+ )
Added: virtaal/branches/upstream/current/virtaal/support/sorted_set.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/support/sorted_set.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/support/sorted_set.py (added)
+++ virtaal/branches/upstream/current/virtaal/support/sorted_set.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,216 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2007-2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+# The file was taken from
+# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/230113
+# and was written by Raymond Hettinger.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+""" altsets.py -- An alternate implementation of Sets.py
+
+Implements set operations using sorted lists as the underlying data structure.
+
+Advantages:
+
+ - Space savings -- lists are much more compact than a dictionary
+ based implementation.
+
+ - Flexibility -- elements do not need to be hashable, only __cmp__
+ is required.
+
+ - Fast operations depending on the underlying data patterns.
+ Non-overlapping sets get united, intersected, or differenced
+ with only log(N) element comparisons. Results are built using
+ fast-slicing.
+
+ - Algorithms are designed to minimize the number of compares
+ which can be expensive.
+
+ - Natural support for sets of sets. No special accomodation needs to
+ be made to use a set or dict as a set member, but users need to be
+ careful to not mutate a member of a set since that may breaks its
+ sort invariant.
+
+Disadvantages:
+
+ - Set construction uses list.sort() with potentially N log(N)
+ comparisons.
+
+ - Membership testing and element addition use log(N) comparisons.
+ Element addition uses list.insert() with takes O(N) time.
+
+ToDo:
+
+ - Make the search routine adapt to the data; falling backing to
+ a linear search when encountering random data.
+
+"""
+
+from bisect import bisect_left
+
+import gobject
+
+
+class SortedSet(gobject.GObject):
+ __gtype_name__ = "SortedSet"
+
+ __gsignals__ = {
+ "removed": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_INT, gobject.TYPE_PYOBJECT)),
+ "added": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_INT, gobject.TYPE_PYOBJECT)),
+ "before-remove": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_INT, gobject.TYPE_PYOBJECT)),
+ "before-add": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_INT, gobject.TYPE_PYOBJECT))
+ }
+
+ def __init__(self, iterable):
+ gobject.GObject.__init__(self)
+
+ data = list(iterable)
+ data.sort()
+ result = data[:1]
+ for elem in data[1:]:
+ if elem == result[-1]:
+ continue
+ result.append(elem)
+ self.data = result
+
+ def __repr__(self):
+ return 'SortedSet(' + repr(self.data) + ')'
+
+ def __iter__(self):
+ return iter(self.data)
+
+ def __contains__(self, elem):
+ data = self.data
+ i = bisect_left(self.data, elem, 0)
+ return i<len(data) and data[i] == elem
+
+ def add(self, elem):
+ if elem not in self:
+ i = bisect_left(self.data, elem)
+ self.emit('before-add', i, elem)
+ self.data.insert(i, elem)
+ self.emit('added', i, elem)
+
+ def remove(self, elem):
+ data = self.data
+ i = bisect_left(self.data, elem, 0)
+ if i<len(data) and data[i] == elem:
+ elem = data[i]
+ self.emit('before-remove', i, elem)
+ del data[i]
+ self.emit('removed', i, elem)
+
+ def _getotherdata(other):
+ if not isinstance(other, SortedSet):
+ other = SortedSet(other)
+ return other.data
+ _getotherdata = staticmethod(_getotherdata)
+
+ def __cmp__(self, other, cmp=cmp):
+ return cmp(self.data, SortedSet._getotherdata(other))
+
+ def union(self, other, find=bisect_left):
+ i = j = 0
+ x = self.data
+ y = SortedSet._getotherdata(other)
+ result = SortedSet([])
+ append = result.data.append
+ extend = result.data.extend
+ try:
+ while 1:
+ if x[i] == y[j]:
+ append(x[i])
+ i += 1
+ j += 1
+ elif x[i] > y[j]:
+ cut = find(y, x[i], j)
+ extend(y[j:cut])
+ j = cut
+ else:
+ cut = find(x, y[j], i)
+ extend(x[i:cut])
+ i = cut
+ except IndexError:
+ extend(x[i:])
+ extend(y[j:])
+ return result
+
+ def intersection(self, other, find=bisect_left):
+ i = j = 0
+ x = self.data
+ y = SortedSet._getotherdata(other)
+ result = SortedSet([])
+ append = result.data.append
+ try:
+ while 1:
+ if x[i] == y[j]:
+ append(x[i])
+ i += 1
+ j += 1
+ elif x[i] > y[j]:
+ j = find(y, x[i], j)
+ else:
+ i = find(x, y[j], i)
+ except IndexError:
+ pass
+ return result
+
+ def difference(self, other, find=bisect_left):
+ i = j = 0
+ x = self.data
+ y = SortedSet._getotherdata(other)
+ result = SortedSet([])
+ extend = result.data.extend
+ try:
+ while 1:
+ if x[i] == y[j]:
+ i += 1
+ j += 1
+ elif x[i] > y[j]:
+ j = find(y, x[i], j)
+ else:
+ cut = find(x, y[j], i)
+ extend(x[i:cut])
+ i = cut
+ except IndexError:
+ extend(x[i:])
+ return result
+
+ def symmetric_difference(self, other, find=bisect_left):
+ i = j = 0
+ x = self.data
+ y = SortedSet._getotherdata(other)
+ result = SortedSet([])
+ extend = result.data.extend
+ try:
+ while 1:
+ if x[i] == y[j]:
+ i += 1
+ j += 1
+ elif x[i] > y[j]:
+ cut = find(y, x[i], j)
+ extend(y[j:cut])
+ j = cut
+ else:
+ cut = find(x, y[j], i)
+ extend(x[i:cut])
+ i = cut
+ except IndexError:
+ extend(x[i:])
+ extend(y[j:])
+ return result
Added: virtaal/branches/upstream/current/virtaal/terminology.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/terminology.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/terminology.py (added)
+++ virtaal/branches/upstream/current/virtaal/terminology.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,71 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+__all__ = ['get_terminology_matcher',
+ 'set_terminology_source']
+
+import os
+import os.path as path
+
+from translate.storage import factory
+
+import pan_app
+from translate.search import match
+
+
+match_store = None # This is if the user specifies a terminology file (as opposed to a directory) on the commmand line
+matchers = {}
+
+def get_terminology_directory():
+ return pan_app.settings.general["terminology-dir"]
+
+def get_suggestion_stores(lang_code):
+ """Return a suggestion store which is an amalgamation of all the translation
+ stores under <termininology_directory>/<lang_code>."""
+ if match_store != None:
+ yield match_store
+ else:
+ for base, _dirnames, filenames in os.walk(path.join(get_terminology_directory(), lang_code)):
+ for filename in filenames:
+ try: # Try to load filename as a translation store...
+ yield factory.getobject(path.join(base, filename))
+ except ValueError: # If filename isn't a translation store, we just do nothing
+ pass
+
+def get_terminology_matcher(lang_code):
+ """Return a terminology matcher based on a translation store which is an
+ amalgamation of all translation stores under
+ <termininology_directory>/<lang_code>
+
+ <termininology_directory> is the globally specified termininology directory.
+ <lang_code> is the supplied parameter.
+
+ @return: a translate.search.match.terminologymatcher"""
+ if lang_code not in matchers:
+ stores = list(get_suggestion_stores(pan_app.settings.language["contentlang"]))
+ matchers[lang_code] = match.terminologymatcher(stores)
+ return matchers[lang_code]
+
+def set_terminology_source(src):
+ global match_store
+ if isinstance(src, (str, unicode)):
+ pan_app.settings.general["terminology-dir"] = src
+ else:
+ match_store = src
Added: virtaal/branches/upstream/current/virtaal/tips.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/tips.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/tips.py (added)
+++ virtaal/branches/upstream/current/virtaal/tips.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,31 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2007-2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+"""These are some tips that are displayed to the user."""
+
+tips = [
+ _("At the end of a translation, simply press <Enter> to continue with the next one."),
+ _("To copy the original string into the target field, simply press <Alt+Down>."),
+ _("When editing a fuzzy translation, the fuzzy marker will automatically be removed."),
+ # l10n: Refer to the translation of "Fuzzy" to find the appropriate shortcut key to recommend
+ _("To mark the current translation as fuzzy, simply press <Alt+U>."),
+ _("Use Ctrl+Up or Ctrl+Down to move between translations."),
+ _("Use Ctrl+PgUp or Ctrl+PgDown to move in large steps between translations."),
+]
Added: virtaal/branches/upstream/current/virtaal/undo_buffer.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/undo_buffer.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/undo_buffer.py (added)
+++ virtaal/branches/upstream/current/virtaal/undo_buffer.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,125 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+"""This provides the data structure for keeping the undo data."""
+
+import collections
+
+import pan_app
+from support.partial import partial
+
+
+class BoundedQueue(collections.deque):
+ def __init__(self, get_size):
+ super(BoundedQueue, self).__init__()
+ self.current_pos = 0
+ self.get_size = get_size
+
+ def push(self, item):
+ while len(self) > self.get_size():
+ self.popleft()
+ self.append(item)
+
+
+def add_undo_to_buffer(buf):
+ buf.__undo_stack = BoundedQueue(lambda: pan_app.settings.undo['depth'])
+ buf.insert_handler = buf.connect("insert-text", on_insert_text, buf.__undo_stack)
+ buf.delete_handler = buf.connect("delete-range", on_delete_range, buf.__undo_stack)
+ return buf
+
+def block_change_signals(buf):
+ buf.handler_block(buf.insert_handler)
+ buf.handler_block(buf.delete_handler)
+
+def unblock_change_signals(buf):
+ buf.handler_unblock(buf.insert_handler)
+ buf.handler_unblock(buf.delete_handler)
+
+def execute_without_signals(buf, action):
+ block_change_signals(buf)
+ result = action()
+ unblock_change_signals(buf)
+ return result
+
+def undo(undo_list):
+ if len(undo_list) > 0:
+ action = undo_list.pop()
+ return action()
+ return False
+
+def on_delete_range(buf, start_iter, end_iter, undo_list):
+ offset = start_iter.get_offset()
+ text = buf.get_text(start_iter, end_iter)
+
+ def undo():
+ buf.delete_selection(False, True)
+ start_iter = buf.get_iter_at_offset(offset)
+ execute_without_signals(buf, partial(buf.insert, start_iter, text))
+ buf.place_cursor(start_iter)
+ return True
+
+ undo_list.push(undo)
+ return True
+
+def on_insert_text(buf, iter, text, length, undo_list):
+ # some weird zero length events waste our time; let's ignore them
+ if length < 1:
+ return True
+ offset = iter.get_offset()
+
+ def undo():
+ buf.delete_selection(False, True)
+ start_iter = buf.get_iter_at_offset(offset)
+ end_iter = buf.get_iter_at_offset(offset + length)
+ execute_without_signals(buf, partial(buf.delete, start_iter, end_iter))
+ buf.place_cursor(start_iter)
+ return True
+
+ undo_list.push(undo)
+ return True
+
+def merge_actions(buf, position):
+ """Combine the last two undo actions into one. This is useful when we are
+ replacing all the buffer contents and such events are seen as a delete
+ followed by an insert.
+
+ @type buf: gtk.TextBuffer
+ @param buf: the buffer where the undo actions should be merged
+ @type position: int
+ @param position: the wanted position of the cursor if these "two"
+ events are to be undone
+ """
+ if hasattr(buf, '__undo_stack'):
+ undostack = buf.__undo_stack
+ if len(undostack) > 1:
+ undos = (undostack.pop(), undostack.pop())
+ def undo():
+ undos[0]() and undos[1]()
+ buf.place_cursor(buf.get_iter_at_offset(position))
+ return True
+
+ else:
+ action = undostack.pop()
+ def undo():
+ action()
+ buf.place_cursor(buf.get_iter_at_offset(position))
+ return True
+
+ undostack.push(undo)
Added: virtaal/branches/upstream/current/virtaal/unit_editor.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/unit_editor.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/unit_editor.py (added)
+++ virtaal/branches/upstream/current/virtaal/unit_editor.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,158 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2007-2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+import gobject
+import pango
+import gtk
+
+from translate.misc.multistring import multistring
+from translate.lang import factory
+
+import pan_app
+import markup
+import undo_buffer
+import unit_layout
+import widgets.label_expander as label_expander
+from support.simplegeneric import generic
+
+
+ at generic
+def compute_optimal_height(widget, width):
+ raise NotImplementedError()
+
+ at compute_optimal_height.when_type(gtk.Widget)
+def gtk_widget_compute_optimal_height(widget, width):
+ pass
+
+ at compute_optimal_height.when_type(gtk.Container)
+def gtk_container_compute_optimal_height(widget, width):
+ for child in widget.get_children():
+ compute_optimal_height(child, width)
+
+ at compute_optimal_height.when_type(gtk.Table)
+def gtk_table_compute_optimal_height(widget, width):
+ for child in widget.get_children():
+ # width / 2 because we use half of the available width
+ compute_optimal_height(child, width / 2)
+
+def make_pango_layout(widget, text, width):
+ pango_layout = pango.Layout(widget.get_pango_context())
+ pango_layout.set_width(width * pango.SCALE)
+ pango_layout.set_wrap(pango.WRAP_WORD_CHAR)
+ pango_layout.set_text(text or "")
+ return pango_layout
+
+ at compute_optimal_height.when_type(gtk.TextView)
+def gtk_textview_compute_optimal_height(widget, width):
+ buf = widget.get_buffer()
+ # For border calculations, see gtktextview.c:gtk_text_view_size_request in the GTK source
+ border = 2 * widget.border_width - 2 * widget.parent.border_width
+ if widget.style_get_property("interior-focus"):
+ border += 2 * widget.style_get_property("focus-line-width")
+
+ buftext = buf.get_text(buf.get_start_iter(), buf.get_end_iter())
+ if not buftext:
+ buftext = getattr(widget, '_source_text', "")
+
+ _w, h = make_pango_layout(widget, buftext, width - border).get_pixel_size()
+ widget.parent.set_size_request(-1, h + border)
+
+ at compute_optimal_height.when_type(label_expander.LabelExpander)
+def gtk_labelexpander_compute_optimal_height(widget, width):
+ if widget.label.child.get_text().strip() == "":
+ widget.set_size_request(-1, 0)
+ else:
+ _w, h = make_pango_layout(widget, widget.label.child.get_label()[0], width).get_pixel_size()
+ widget.set_size_request(-1, h + 4)
+
+
+class UnitEditor(gtk.EventBox, gtk.CellEditable):
+ """Text view suitable for cell renderer use."""
+
+ __gtype_name__ = "UnitEditor"
+
+ __gsignals__ = {
+ 'modified':(gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ())
+ }
+
+ def __init__(self, parent, unit):
+ gtk.EventBox.__init__(self)
+ self._document = parent.document
+ self.layout = unit_layout.build_layout(unit, self._document.nplurals)
+ self.add(self.layout)
+ self.sources = [src for src in unit_layout.get_sources(self.layout)]
+ self.targets = []
+ for target in unit_layout.get_targets(self.layout):
+ target.connect('key-press-event', self._on_text_view_key_press_event)
+ target.get_buffer().connect("changed", self._on_modify)
+ self.targets.append(target)
+ for option in unit_layout.get_options(self.layout):
+ option.connect("toggled", self._on_modify)
+ self.must_advance = False
+ self._modified = False
+ self._unit = unit
+ self.connect('key-press-event', self._on_key_press_event)
+
+ def _on_modify(self, _buf):
+ self.emit('modified')
+
+ def _on_key_press_event(self, _widget, event, *_args):
+ if event.keyval == gtk.keysyms.Return or event.keyval == gtk.keysyms.KP_Enter:
+ self.must_advance = True
+ self.editing_done()
+ return True
+ return False
+
+ def _on_text_view_key_press_event(self, widget, event, *_args):
+ # Alt-Down
+ if event.keyval == gtk.keysyms.Down and event.state & gtk.gdk.MOD1_MASK:
+ gobject.idle_add(self.copy_original, widget)
+ return True
+ return False
+
+ def do_start_editing(self, *_args):
+ """Start editing."""
+ unit_layout.focus_text_view(unit_layout.get_targets(self)[0])
+
+ def get_modified(self):
+ return self._modified
+
+ def get_text(self):
+ targets = [b.props.text for b in self.buffers]
+ if len(targets) == 1:
+ return targets[0]
+ else:
+ return multistring(targets)
+
+ def copy_original(self, text_view):
+ buf = text_view.get_buffer()
+ position = buf.props.cursor_position
+ lang = factory.getlanguage(self._document.get_target_language())
+ new_source = lang.punctranslate(self._unit.source)
+ # if punctranslate actually changed something, let's insert that as an
+ # undo step
+ if new_source != self._unit.source:
+ buf.set_text(markup.escape(self._unit.source))
+ # TODO: consider a better position to return to on undo
+ undo_buffer.merge_actions(buf, position)
+ buf.set_text(markup.escape(new_source))
+ undo_buffer.merge_actions(buf, position)
+ unit_layout.focus_text_view(text_view)
+ return False
Added: virtaal/branches/upstream/current/virtaal/unit_layout.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/unit_layout.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/unit_layout.py (added)
+++ virtaal/branches/upstream/current/virtaal/unit_layout.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,360 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2007-2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+__all__ = ['build_layout', 'get_targets', 'get_options']
+
+import logging
+import re
+
+import gtk
+try:
+ import gtkspell
+except ImportError, e:
+ gtkspell = None
+
+import pan_app
+import rendering
+import markup
+import undo_buffer
+from support.partial import partial
+from widgets import label_expander, util
+from terminology import get_terminology_matcher
+
+
+def get_sources(widget):
+ def add_sources_to_list(lst):
+ def do(widget):
+ if '_is_source' in widget.__dict__:
+ lst.append(widget)
+ return do
+
+ result = []
+ util.forall_widgets(add_sources_to_list(result), widget)
+ return result
+
+def get_targets(widget):
+ def add_targets_to_list(lst):
+ def do(widget):
+ if '_is_target' in widget.__dict__:
+ lst.append(widget)
+ return do
+
+ result = []
+ util.forall_widgets(add_targets_to_list(result), widget)
+ return result
+
+def get_options(widget):
+ def add_options_to_list(lst):
+ def do(widget):
+ if isinstance(widget, gtk.CheckButton):
+ lst.append(widget)
+ return do
+
+ result = []
+ util.forall_widgets(add_options_to_list(result), widget)
+ return result
+
+
+#A regular expression to help us find a meaningful place to position the
+#cursor initially.
+first_word_re = re.compile("(?m)(?u)^(<[^>]+>|\\\\[nt]|[\W$^\n])*(\\b|\\Z)")
+
+def focus_text_view(text_view):
+ text_view.grab_focus()
+
+ buf = text_view.get_buffer()
+ text = buf.get_text(buf.get_start_iter(), buf.get_end_iter())
+
+ translation_start = first_word_re.match(text).span()[1]
+ buf.place_cursor(buf.get_iter_at_offset(translation_start))
+
+################################################################################
+
+def add_events(widget):
+ def on_key_press_event(widget, event, *_args):
+ if event.keyval == gtk.keysyms.Return or event.keyval == gtk.keysyms.KP_Enter:
+ widget.parent.emit('key-press-event', event)
+ return True
+ return False
+
+ # Skip Enter key processing
+ widget.connect('key-press-event', on_key_press_event)
+ return widget
+
+def layout(left=None, middle=None, right=None):
+ table = gtk.Table(rows=1, columns=4, homogeneous=True)
+ if left != None:
+ table.attach(left, 0, 1, 0, 1, xoptions=gtk.FILL|gtk.EXPAND, yoptions=gtk.FILL)
+ if middle != None:
+ table.attach(middle, 1, 3, 0, 1, xoptions=gtk.FILL|gtk.EXPAND, yoptions=gtk.FILL)
+ if right != None:
+ table.attach(right, 3, 4, 0, 1, xoptions=gtk.FILL|gtk.EXPAND, yoptions=gtk.FILL)
+ return add_events(table)
+
+def fill_list(lst, children):
+ for child in children:
+ lst.pack_start(child, fill=True, expand=False)
+ return lst
+
+def vlist(*children):
+ return add_events(fill_list(gtk.VBox(), children))
+
+def hlist(*children):
+ return fill_list(gtk.HBox(), children)
+
+def add_spell_checking(text_view, language):
+ global gtkspell
+ if gtkspell:
+ try:
+ spell = gtkspell.Spell(text_view)
+ spell.set_language(language)
+ except:
+ logging.info("Could not initialize spell checking")
+ gtkspell = None
+ return text_view
+
+def set_text(text_view, txt):
+ text_view.get_buffer().set_text(markup.escape(txt))
+ return text_view
+
+def text_view(editable):
+ text_view = gtk.TextView()
+ text_view.set_editable(editable)
+ text_view.set_wrap_mode(gtk.WRAP_WORD)
+ text_view.set_border_window_size(gtk.TEXT_WINDOW_TOP, 1)
+ return text_view
+
+def scrolled_window(widget, scroll_vertical=gtk.POLICY_AUTOMATIC, add_viewport=False):
+ scrolled_window = gtk.ScrolledWindow()
+ scrolled_window.set_policy(gtk.POLICY_NEVER, scroll_vertical)
+ if not add_viewport:
+ scrolled_window.add(widget)
+ else:
+ scrolled_window.add_with_viewport(widget)
+ return add_events(scrolled_window)
+
+def make_scrolled_text_view(get_text, editable, scroll_vertical, language):
+ return scrolled_window(
+ add_spell_checking(
+ set_text(
+ text_view(editable),
+ get_text()),
+ pan_app.settings.language[language]),
+ scroll_vertical)
+
+def source_text_box(get_text, set_text):
+ scrolled_window = make_scrolled_text_view(get_text, False, gtk.POLICY_NEVER, "sourcelang")
+ text_view = scrolled_window.get_child()
+ text_view.modify_font(rendering.get_source_font_description())
+ # This causes some problems, so commented out for now
+ #text_view.get_pango_context().set_font_description(rendering.get_source_font_description())
+ text_view.get_pango_context().set_language(rendering.get_source_language())
+ text_view._is_source = True
+ return scrolled_window
+
+def target_text_box(get_text, set_text, source_text):
+ def get_range(buf, left_offset, right_offset):
+ return buf.get_text(buf.get_iter_at_offset(left_offset),
+ buf.get_iter_at_offset(right_offset))
+
+ def on_text_view_n_press_event(text_view, event):
+ """Handle special keypresses in the textarea."""
+ # Automatically move to the next line if \n is entered
+
+ if event.keyval == gtk.keysyms.n:
+ buf = text_view.get_buffer()
+ if get_range(buf, buf.props.cursor_position-1, buf.props.cursor_position) == "\\":
+ buf.insert_at_cursor('n\n')
+ text_view.scroll_mark_onscreen(buf.get_insert())
+ return True
+ return False
+
+ def on_change(buf):
+ set_text(markup.unescape(buf.get_text(buf.get_start_iter(), buf.get_end_iter())))
+
+ scrolled_window = make_scrolled_text_view(get_text, True, gtk.POLICY_AUTOMATIC, "contentlang")
+ text_view = scrolled_window.get_child()
+ text_view.modify_font(rendering.get_target_font_description())
+ text_view.get_pango_context().set_font_description(rendering.get_target_font_description())
+ text_view.get_pango_context().set_language(rendering.get_target_language())
+ text_view.connect('key-press-event', on_text_view_n_press_event)
+ text_view._is_target = True
+ text_view._source_text = source_text
+
+ buf = undo_buffer.add_undo_to_buffer(text_view.get_buffer())
+ undo_buffer.execute_without_signals(buf, lambda: buf.set_text(markup.escape(get_text())))
+ buf.connect('changed', on_change)
+
+ return scrolled_window
+
+def connect_target_text_views(child):
+ def target_key_press_event(text_view, event, next_text_view):
+ if event.keyval == gtk.keysyms.Return or event.keyval == gtk.keysyms.KP_Enter:
+ focus_text_view(next_text_view)
+ return True
+ return False
+
+ def end_target_key_press_event(text_view, event, *_args):
+ if event.keyval == gtk.keysyms.Return or event.keyval == gtk.keysyms.KP_Enter:
+ text_view.parent.emit('key-press-event', event)
+ return True
+ return False
+
+ targets = get_targets(child)
+ for target, next_target in zip(targets, targets[1:]):
+ target.connect('key-press-event', target_key_press_event, next_target)
+ targets[-1].connect('key-press-event', end_target_key_press_event)
+ return child
+
+def comment(get_text, set_text=lambda value: None):
+ text_box = source_text_box(get_text, set_text)
+ return label_expander.LabelExpander(text_box, get_text)
+
+def option(label, get_option, set_option):
+ def on_toggled(widget, *_args):
+ if widget.get_active():
+ set_option(True)
+ else:
+ set_option(False)
+
+ check_button = gtk.CheckButton(label=label)
+ check_button.connect('toggled', on_toggled)
+ check_button.set_active(get_option())
+ # FIXME: not allowing focus willprobably raise various issues related to keyboard accesss.
+ check_button.set_property("can-focus", False)
+ return check_button
+
+def terminology_source(txt):
+ label = gtk.Label()
+ label.set_justify(gtk.JUSTIFY_RIGHT)
+ label.set_markup("<b>%s</b>:" % txt)
+ return label
+
+def terminology_target(txt):
+ label = gtk.Label()
+ label.set_justify(gtk.JUSTIFY_LEFT)
+ label.set_text(txt)
+ return label
+
+def list_model(types, data_list):
+ model = gtk.ListStore(*types)
+ for data_row in data_list:
+ last_row = model.append()
+ for i, data_element in enumerate(data_row):
+ model.set(last_row, i, data_element)
+ return model
+
+def treeview(model):
+ v = gtk.TreeView(model)
+ v.set_headers_visible(False)
+ text_renderer = gtk.CellRendererText()
+ for i in xrange(model.get_n_columns()):
+ v.append_column(gtk.TreeViewColumn(None, text_renderer, text=i))
+ return v
+
+def terminology_grid(matches):
+ return treeview(list_model([str, str], ((unicode(u.source), unicode(u.target)) for u in matches)))
+
+def terminology_list(sources):
+ matcher = get_terminology_matcher(pan_app.settings.language["contentlang"])
+ results = matcher.matches(" ".join(sources))
+ if len(results) > 0:
+ return scrolled_window(terminology_grid(results))
+ else:
+ return None
+
+################################################################################
+
+def build_layout(unit, nplurals):
+ """Construct a blueprint which can be used to build editor widgets
+ or to compute the height required to display editor widgets; this
+ latter operation is required by the TreeView.
+
+ @param unit: A translation unit used by the translate toolkit.
+ @param nplurals: The number of plurals in the
+ """
+
+ def get(multistring, unit, i):
+ if unit.hasplural():
+ return multistring.strings[i]
+ elif i == 0:
+ return multistring
+ else:
+ raise IndexError()
+
+ def get_source(unit, index):
+ return get(unit.source, unit, index)
+
+ def get_target(unit, nplurals, index):
+ if unit.hasplural() and nplurals != len(unit.target.strings):
+ targets = nplurals * [u""]
+ targets[:len(unit.target.strings)] = unit.target.strings
+ unit.target = targets
+ return get(unit.target, unit, index)
+
+ def set(unit, attr, index, value):
+ if unit.hasplural():
+ str_list = list(getattr(unit, attr).strings)
+ str_list[index] = value
+ setattr(unit, attr, str_list)
+ elif index == 0:
+ setattr(unit, attr, value)
+ else:
+ raise IndexError()
+
+ def set_source(unit, index, value):
+ set(unit, 'source', index, value)
+
+ def set_target(unit, index, value):
+ set(unit, 'target', index, value)
+
+ def num_sources(unit):
+ if unit.hasplural():
+ return len(unit.source.strings)
+ return 1
+
+ def num_targets(unit, nplurals):
+ if unit.hasplural():
+ return nplurals
+ return 1
+
+ first_source = source_text_box(partial(get_source, unit, 0), partial(set_source, unit, 0))
+
+ sources = [source_text_box(partial(get_source, unit, i), partial(set_source, unit, i))
+ for i in xrange(num_sources(unit))]
+
+ targets = [target_text_box(partial(get_target, unit, nplurals, i), partial(set_target, unit, i), unit.source)
+ for i in xrange(num_targets(unit, nplurals))]
+
+ widget = layout(
+ middle=vlist(
+ comment(partial(unit.getnotes, 'programmer')),
+ vlist(*sources),
+ comment(unit.getcontext),
+ connect_target_text_views(
+ vlist(*targets)),
+ comment(partial(unit.getnotes, 'translator')),
+ option(_('F_uzzy'), unit.isfuzzy, unit.markfuzzy)),
+ right=terminology_list([get_source(unit, i) for i in xrange(num_sources(unit))]))
+
+ widget.sources = sources
+ widget.target = targets
+ return widget
+
Added: virtaal/branches/upstream/current/virtaal/unit_renderer.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/unit_renderer.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/unit_renderer.py (added)
+++ virtaal/branches/upstream/current/virtaal/unit_renderer.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,178 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2005-2007 Osmo Salomaa
+# Copyright (C) 2007-2008 Zuza Software Foundation
+#
+# This file was part of Gaupol.
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+
+"""Cell renderer for multiline text data."""
+
+import gobject
+import gtk
+import pango
+
+import pan_app
+import rendering
+import markup
+import undo_buffer
+import unit_editor
+
+
+def undo(tree_view):
+ undo_buffer.undo(tree_view.get_buffer().__undo_stack)
+
+
+class UnitRenderer(gtk.GenericCellRenderer):
+ """Cell renderer for multiline text data."""
+
+ __gtype_name__ = "UnitRenderer"
+
+ __gproperties__ = {
+ "unit": (gobject.TYPE_PYOBJECT,
+ "The unit",
+ "The unit that this renderer is currently handling",
+ gobject.PARAM_READWRITE),
+ "editable": (gobject.TYPE_BOOLEAN,
+ "editable",
+ "A boolean indicating whether this unit is currently editable",
+ False,
+ gobject.PARAM_READWRITE),
+ }
+
+ __gsignals__ = {
+ "editing-done": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ (gobject.TYPE_STRING, gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN)),
+ "modified": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ())
+ }
+
+ ROW_PADDING = 10
+ """The number of pixels between rows."""
+
+ def __init__(self, parent):
+ gtk.GenericCellRenderer.__init__(self)
+ self.set_property('mode', gtk.CELL_RENDERER_MODE_EDITABLE)
+ self.parent = parent
+ self.__unit = None
+ self.editable = False
+ self._editor = None
+ self.source_layout = None
+ self.target_layout = None
+
+ def _get_unit(self):
+ return self.__unit
+
+ def _set_unit(self, value):
+ if value.isfuzzy():
+ self.props.cell_background = "gray"
+ self.props.cell_background_set = True
+ else:
+ self.props.cell_background_set = False
+ self.__unit = value
+
+ unit = property(_get_unit, _set_unit, None, None)
+
+ def do_set_property(self, pspec, value):
+ setattr(self, pspec.name, value)
+
+ def do_get_property(self, pspec):
+ return getattr(self, pspec.name)
+
+ def on_render(self, window, widget, _background_area, cell_area, _expose_area, _flags):
+ if self.editable:
+ return True
+ x_offset, y_offset, width, _height = self.do_get_size(widget, cell_area)
+ x = cell_area.x + x_offset
+ y = cell_area.y + y_offset
+ source_x = x
+ target_x = x
+ if widget.get_direction() == gtk.TEXT_DIR_LTR:
+ target_x += width/2
+ else:
+ source_x += width/2
+ widget.get_style().paint_layout(window, gtk.STATE_NORMAL, False,
+ cell_area, widget, '', source_x, y, self.source_layout)
+ widget.get_style().paint_layout(window, gtk.STATE_NORMAL, False,
+ cell_area, widget, '', target_x, y, self.target_layout)
+
+ def _get_pango_layout(self, widget, text, width, font_description):
+ '''Gets the Pango layout used in the cell in a TreeView widget.'''
+ # We can't use widget.get_pango_context() because we'll end up
+ # overwriting the language and font settings if we don't have a
+ # new one
+ layout = pango.Layout(widget.create_pango_context())
+ layout.set_font_description(font_description)
+ layout.set_wrap(pango.WRAP_WORD_CHAR)
+ layout.set_width(width * pango.SCALE)
+ #XXX - plurals?
+ text = text or ""
+ layout.set_markup(markup.markuptext(text))
+ return layout
+
+ def compute_cell_height(self, widget, width):
+ self.source_layout = self._get_pango_layout(widget, self.unit.source, width / 2,
+ rendering.get_source_font_description())
+ self.source_layout.get_context().set_language(rendering.get_source_language())
+ self.target_layout = self._get_pango_layout(widget, self.unit.target, width / 2,
+ rendering.get_target_font_description())
+ self.target_layout.get_context().set_language(rendering.get_target_language())
+ # This makes no sense, but has the desired effect to align things correctly for
+ # both LTR and RTL languages:
+ if widget.get_direction() == gtk.TEXT_DIR_RTL:
+ self.source_layout.set_alignment(pango.ALIGN_RIGHT)
+ self.target_layout.set_alignment(pango.ALIGN_RIGHT)
+ _layout_width, source_height = self.source_layout.get_pixel_size()
+ _layout_width, target_height = self.target_layout.get_pixel_size()
+ return max(source_height, target_height) + self.ROW_PADDING
+
+ def do_get_size(self, widget, _cell_area):
+ #TODO: store last unitid and computed dimensions
+ width = widget.get_toplevel().get_allocation().width - 32
+ if self.editable:
+ editor = self.get_editor(widget)
+ editor.set_size_request(width, -1)
+ unit_editor.compute_optimal_height(editor, width)
+ _width, height = editor.size_request()
+ else:
+ height = self.compute_cell_height(widget, width)
+ height = min(height, 600)
+ y_offset = self.ROW_PADDING / 2
+ return 0, y_offset, width, height
+
+ def _on_editor_done(self, editor):
+ self.emit("editing-done", editor.get_data("path"), editor.must_advance, editor.get_modified())
+ return True
+
+ def _on_modified(self, widget):
+ self.emit("modified")
+
+ def get_editor(self, parent):
+ if not hasattr(self.unit, '__editor'):
+ editor = unit_editor.UnitEditor(parent, self.unit)
+ editor.connect("editing-done", self._on_editor_done)
+ editor.connect("modified", self._on_modified)
+ editor.set_border_width(min(self.props.xpad, self.props.ypad))
+ editor.show_all()
+ setattr(self.unit, '__editor', editor)
+ return getattr(self.unit, '__editor')
+
+ def do_start_editing(self, _event, tree_view, path, _bg_area, cell_area, _flags):
+ """Initialize and return the editor widget."""
+ editor = self.get_editor(tree_view)
+ editor.set_size_request(cell_area.width, cell_area.height)
+ return editor
Added: virtaal/branches/upstream/current/virtaal/widgets/__init__.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/widgets/__init__.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/widgets/__init__.py (added)
+++ virtaal/branches/upstream/current/virtaal/widgets/__init__.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,19 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
Added: virtaal/branches/upstream/current/virtaal/widgets/entry_dialog.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/widgets/entry_dialog.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/widgets/entry_dialog.py (added)
+++ virtaal/branches/upstream/current/virtaal/widgets/entry_dialog.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,46 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+"""This provides a simple dialog with a text entry field."""
+
+import gtk
+
+
+def EntryDialog(title):
+ dlg = gtk.Dialog(title)
+ dlg.set_size_request(450, 100)
+ dlg.show()
+
+ entry = gtk.Entry()
+ entry.show()
+ entry.set_activates_default(True)
+ dlg.vbox.pack_start(entry)
+
+ dlg.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
+ dlg.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
+ dlg.set_default_response(gtk.RESPONSE_OK)
+ entry.grab_focus()
+ response = dlg.run()
+
+ text = None
+ if response == gtk.RESPONSE_OK:
+ text = entry.get_text().decode('utf-8')
+ dlg.destroy()
+ return text
Added: virtaal/branches/upstream/current/virtaal/widgets/label_expander.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/widgets/label_expander.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/widgets/label_expander.py (added)
+++ virtaal/branches/upstream/current/virtaal/widgets/label_expander.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,80 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+import gtk
+import gobject
+import pango
+
+
+def label_escape(text):
+ escapes = [("\n", '\\n'), ("\r", '\\r')]
+ return reduce(lambda text, escape: text.replace(*escape), escapes, text)
+
+
+class LabelExpander(gtk.EventBox):
+ __gproperties__ = {
+ "expanded": (gobject.TYPE_BOOLEAN,
+ "expanded",
+ "A boolean indicating whether this widget has been expanded to show its contained widget",
+ False,
+ gobject.PARAM_READWRITE),
+ }
+
+ def __init__(self, widget, get_text, expanded=False):
+ super(LabelExpander, self).__init__()
+
+ label_text = gtk.Label()
+ label_text.set_single_line_mode(True)
+ label_text.set_ellipsize(pango.ELLIPSIZE_END)
+ label_text.set_justify(gtk.JUSTIFY_LEFT)
+ label_text.set_use_markup(True)
+
+ self.label = gtk.EventBox()
+ self.label.add(label_text)
+
+ self.widget = widget
+ self.get_text = get_text
+
+ self.expanded = expanded
+
+ #self.label.connect('button-release-event', lambda widget, *args: setattr(self, 'expanded', True))
+
+ def do_get_property(self, prop):
+ return getattr(self, prop.name)
+
+ def do_set_property(self, prop, value):
+ setattr(self, prop.name, value)
+
+ def _get_expanded(self):
+ return self.child == self.widget
+
+ def _set_expanded(self, value):
+ if self.child != None:
+ self.remove(self.child)
+
+ if value:
+ self.add(self.widget)
+ else:
+ self.add(self.label)
+ self.label.child.set_text(label_escape(self.get_text()))
+
+ self.child.show()
+
+ expanded = property(_get_expanded, _set_expanded)
Added: virtaal/branches/upstream/current/virtaal/widgets/util.py
URL: http://svn.debian.org/wsvn/virtaal/branches/upstream/current/virtaal/widgets/util.py?rev=1394&op=file
==============================================================================
--- virtaal/branches/upstream/current/virtaal/widgets/util.py (added)
+++ virtaal/branches/upstream/current/virtaal/widgets/util.py Fri Oct 3 19:42:03 2008
@@ -1,0 +1,40 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of Virtaal.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+__all__ = ['forall_widgets']
+
+import gtk
+
+from virtaal.support.simplegeneric import generic
+
+
+ at generic
+def get_children(widget):
+ return []
+
+ at get_children.when_type(gtk.Container)
+def get_children_container(widget):
+ return widget.get_children()
+
+def forall_widgets(f, widget):
+ f(widget)
+ for child in get_children(widget):
+ forall_widgets(f, child)
+
More information about the Debian-l10n-commits
mailing list