Package translate :: Package storage :: Module qph

[hide private]
[frames] | no frames]

# Source Code for Module translate.storage.qph

      1  #!/usr/bin/env python
      2  # -*- coding: utf-8 -*-
      3  #
      4  # Copyright 2008 Zuza Software Foundation
      5  #
      6  # This file is part of translate.
      7  #
      8  # translate is free software; you can redistribute it and/or modify
      9  # it under the terms of the GNU General Public License as published by
     10  # the Free Software Foundation; either version 2 of the License, or
     11  # (at your option) any later version.
     12  #
     13  # translate is distributed in the hope that it will be useful,
     14  # but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  # GNU General Public License for more details.
     17  #
     18  # You should have received a copy of the GNU General Public License
     19  # along with translate; if not, write to the Free Software
     20  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     21  #
     22
     23  """Module for handling Qt Phrase Book (.qph) files.
     24
     25  Extract from the U{Qt Linguist Manual:
     26  Translators<http://doc.trolltech.com/4.3/linguist-translators.html>}:
     27  .qph Qt Phrase Book Files are human-readable XML files containing standard
     28  phrases and their translations. These files are created and updated by Qt
     29  Linguist and may be used by any number of projects and applications.
     30  """
     31
     32  from translate.storage import lisa
     33  from translate.misc.multistring import multistring
     34  from lxml import etree
     35
     36 -class QphUnit(lisa.LISAunit):
     37      """A single term in the qph file."""
     38
     39      rootNode = "phrase"
     40      languageNode = "source"
     41      textNode = ""
     42      namespace = ''
     43
     44 -    def createlanguageNode(self, lang, text, purpose):
     45          """Returns an xml Element setup with given parameters."""
     46          assert purpose
     47          langset = etree.Element(self.namespaced(purpose))
     48          langset.text = text
     49          return langset
     50
     51 -    def _getsourcenode(self):
     52          return self.xmlelement.find(self.namespaced(self.languageNode))
     53
     54 -    def _gettargetnode(self):
     55          return self.xmlelement.find(self.namespaced("target"))
     56
     57 -    def getlanguageNodes(self):
     58          """We override this to get source and target nodes."""
     59          def not_none(node):
     60              return not node is None
     61          return filter(not_none, [self._getsourcenode(), self._gettargetnode()])
     62
     63 -    def settarget(self, text):
     64          #Firstly deal with reinitialising to None or setting to identical string
     65          if self.gettarget() == text:
     66              return
     67          self._gettargetnode().text = text
     68
     69 -    def gettarget(self):
     70          targetnode = self._gettargetnode()
     71          if targetnode is None:
     72              etree.SubElement(self.xmlelement, self.namespaced("target"))
     73              return None
     74          return targetnode.text or ""
     75      target = property(gettarget, settarget)
     76
     77 -    def addnote(self, text, origin=None):
     78          """Add a note specifically in a "definition" tag"""
     79          assert isinstance(text, unicode)
     80          current_notes = self.getnotes(origin)
     81          self.removenotes()
     82          note = etree.SubElement(self.xmlelement, self.namespaced("definition"))
     83          note.text = "\n".join(filter(None, [current_notes, text.strip()]))
     84
     85 -    def getnotes(self, origin=None):
     86          #TODO: consider only responding when origin has certain values
     87          notenode = self.xmlelement.find(self.namespaced("definition"))
     88          comment = ''
     89          if not notenode is None:
     90              comment = notenode.text
     91          return comment
     92
     93 -    def removenotes(self):
     94          """Remove all the translator notes."""
     95          note = self.xmlelement.find(self.namespaced("comment"))
     96          if not note is None:
     97              self.xmlelement.remove(note)
     98
     99 -    def getid(self):
    100          return self.source
    101
    102 -    def merge(self, otherunit, overwrite=False, comments=True):
    103          super(QphUnit, self).merge(otherunit, overwrite, comments)
    104
    105
    106 -class QphFile(lisa.LISAfile):
    107      """Class representing a QPH file store."""
    108      UnitClass = QphUnit
    109      Name = "Qt Phrase Book File"
    110      Mimetypes  = ["application/x-qph"]
    111      Extensions = ["qph"]
    112      rootNode = "QPH"
    113      # We will switch out .body to fit with the context we are working on
    114      bodyNode = "context"
    115      XMLskeleton = '''<!DOCTYPE QPH>
    116  <QPH>
    117  </QPH>
    118  '''
    119      namespace = ''
    120
    121 -    def __init__(self, *args, **kwargs):
    122          self._contextname = None
    123          lisa.LISAfile.__init__(self, *args, **kwargs)
    124
    125 -    def initbody(self):
    126          """Initialises self.body."""
    127          self.namespace = self.document.getroot().nsmap.get(None, None)
    128          if self._contextname:
    129              self.body = self.getcontextnode(self._contextname)
    130          else:
    131              self.body = self.document.getroot()
    132
    133 -    def createcontext(self, contextname, comment=None):
    134          """Creates a context node with an optional comment"""
    135          context = etree.SubElement(self.document.getroot(), self.namespaced(self.bodyNode))
    136          if comment:
    137              comment_node = context.SubElement(context, "comment")
    138              comment_node.text = comment
    139          return context
    140
    141 -    def getcontextname(self, contextnode):
    142          """Returns the name of the given context."""
    143          return filenode.find(self.namespaced("name")).text
    144
    145 -    def getcontextnames(self):
    146          """Returns all contextnames in this TS file."""
    147          contextnodes = self.document.findall(self.namespaced("context"))
    148          contextnames = [self.getcontextname(contextnode) for contextnode in contextnodes]
    149          contextnames = filter(None, contextnames)
    150          if len(contextnames) == 1 and contextnames[0] == '':
    151              contextnames = []
    152          return contextnames
    153
    154 -    def getcontextnode(self, contextname):
    155          """Finds the contextnode with the given name."""
    156          contextnodes = self.document.findall(self.namespaced("context"))
    157          for contextnode in contextnodes:
    158              if self.getcontextname(contextnode) == contextname:
    159                  return contextnode
    160          return None
    161
    162 -    def addunit(self, unit, new=True, contextname=None, createifmissing=False):
    163          """adds the given trans-unit to the last used body node if the contextname has changed it uses the slow method instead (will create the nodes required if asked). Returns success"""
    164          if self._contextname != contextname:
    165              if not self.switchcontext(contextname, createifmissing):
    166                  return None
    167          super(QphFile, self).addunit(unit, new)
    168  #        unit._context_node = self.getcontextnode(self._contextname)
    169  #        lisa.setXMLspace(unit.xmlelement, "preserve")
    170          return unit
    171
    172 -    def switchcontext(self, contextname, createifmissing=False):
    173          """Switch the current context to the one named contextname, optionally
    174          creating it if it doesn't exist."""
    175          self._context_name = contextname
    176          contextnode = self.getcontextnode(contextname)
    177          if contextnode is None:
    178              if not createifmissing:
    179                  return False
    180              contextnode = self.createcontextnode(contextname)
    181              self.document.getroot().append(contextnode)
    182
    183          self.body = contextnode
    184          if self.body is None:
    185              return False
    186          return True
    187