[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