Index: translate/storage/test_cpo.py =================================================================== --- translate/storage/test_cpo.py (revision 7897) +++ translate/storage/test_cpo.py (working copy) @@ -72,6 +72,17 @@ unit.addnote("# Double commented comment") assert unit.getnotes() == "# Double commented comment" + def test_context(self): + """tests if we handle msgctxt properly""" + unit = self.UnitClass("content") + assert unit.getcontext() == "" + + unit.setcontext("content context") + assert unit.getcontext() == "content context" + + unit.setcontext("") + assert unit.getcontext() == "" + class TestCPOFile(test_po.TestPOFile): StoreClass = cpo.pofile def test_msgidcomments(self): Index: translate/storage/cpo.py =================================================================== --- translate/storage/cpo.py (revision 7897) +++ translate/storage/cpo.py (working copy) @@ -513,6 +513,11 @@ else: return msgidcomment + def setcontext(self, context): + """Sets the current context for this unit""" + # TODO: find out what behavior this should really have + gpo.po_message_set_msgctxt(self._gpo_message, context) + class pofile(pocommon.pofile): UnitClass = pounit def __init__(self, inputfile=None, encoding=None, unitclass=pounit): Index: translate/convert/xliff2po.py =================================================================== --- translate/convert/xliff2po.py (revision 7897) +++ translate/convert/xliff2po.py (working copy) @@ -42,6 +42,11 @@ thepo.source = transunit.source thepo.target = transunit.target + #Context + context = transunit.getcontext_message() + if context: + thepo.setcontext(context) + #Location comments locations = transunit.getlocations() if locations: Index: translate/convert/test_xliff2po.py =================================================================== --- translate/convert/test_xliff2po.py (revision 7897) +++ translate/convert/test_xliff2po.py (working copy) @@ -170,7 +170,20 @@ assert potext.index('msgstr[0] "inkomo"') assert potext.index('msgstr[1] "iinkomo"') + def test_xliff_with_context(self): + """tests if we support context strings""" + minixlf = self.xliffskeleton % ''' + gold + ouro + + the precious + +''' + pofile = self.xliff2po(minixlf) + unit = pofile.units[0] + assert unit.getcontext() == "the precious" + class TestBasicXLIFF2PO(TestXLIFF2PO): """This tests a basic XLIFF file without xmlns attribute""" Index: translate/convert/po2xliff.py =================================================================== --- translate/convert/po2xliff.py (revision 7897) +++ translate/convert/po2xliff.py (working copy) @@ -45,6 +45,11 @@ unit.markfuzzy(inputunit.isfuzzy()) else: unit.markapproved(False) + + #Handle msgctxt + context = inputunit.getcontext() + if context: + unit.setcontext_message(context) #Handle #: location comments for location in inputunit.getlocations(): Index: translate/convert/test_po2xliff.py =================================================================== --- translate/convert/test_po2xliff.py (revision 7897) +++ translate/convert/test_po2xliff.py (working copy) @@ -294,3 +294,15 @@ assert xliff.units[2].xmlelement.get("approved") == "no" assert not xliff.units[2].isapproved() + def test_po_with_msgctxt(self): + minipo = 'msgctxt "numbers"\nmsgid "one"\nmsgstr "um"\n' + xliff = self.po2xliff(minipo) + print str(xliff) + node = xliff.units[0].xmlelement + contextgroups = node.findall(".//%s" % xliff.namespaced("context-group")) + assert len(contextgroups) == 1 + for group in contextgroups: + assert group.get("name") == "po-msgctxt" + assert group.get("purpose") == "match information" + tuples = self.getcontexttuples(node, xliff.namespace) + assert tuples == [('x-po-msgctxt', 'numbers')] Index: translate/storage/base.py =================================================================== --- translate/storage/base.py (revision 7897) +++ translate/storage/base.py (working copy) @@ -160,6 +160,10 @@ """Get the message context.""" return "" + def setcontext(self, context): + """Sets the message context""" + pass + def getnotes(self, origin=None): """Returns all notes about this unit. Index: translate/storage/poxliff.py =================================================================== --- translate/storage/poxliff.py (revision 7897) +++ translate/storage/poxliff.py (working copy) @@ -251,7 +251,34 @@ def hasplural(self): return self.xmlelement.tag == self.namespaced("group") + def getcontext_message(self): + """Returns the message context for this unit, if any. + This message context is intended to identify the message that + represents the PO msgctxt. + See http://bugs.locamotion.org/show_bug.cgi?id=258 for details. + """ + groups = self.getcontextgroups("po-msgctxt") + context = "" + if groups: + # groups = [[(context-type, context_message)]] + context = groups[0][0][1] + return context + + def setcontext_message(self, context): + """Sets the message context for this unit. + The message context will be set as the message which represents the + PO msgctxt in XLIFF. + See http://bugs.locamotion.org/show_bug.cgi?id=258 for details. + """ + group_name = "po-msgctxt" + if self.getcontext_message(): + self.delcontextgroup(group_name) + + self.createcontextgroup(group_name, [("x-po-msgctxt", context)], + purpose="match information") + + class PoXliffFile(xliff.xlifffile, poheader.poheader): """a file for the po variant of Xliff files""" UnitClass = PoXliffUnit Index: translate/storage/test_poxliff.py =================================================================== --- translate/storage/test_poxliff.py (revision 7897) +++ translate/storage/test_poxliff.py (working copy) @@ -44,6 +44,17 @@ assert unit.getid() == "20" assert unit.units[1].getid() == "20[1]" + def test_context_message(self): + """tests context messages""" + unit = self.UnitClass("Context") + assert unit.getcontext_message() == "" + + unit.setcontext_message("Testing") + assert unit.getcontext_message() == "Testing" + + unit.setcontext_message("") + assert unit.getcontext_message() == "" + class TestPOXLIFFfile(test_xliff.TestXLIFFfile): StoreClass = poxliff.PoXliffFile xliffskeleton = ''' Index: translate/storage/xliff.py =================================================================== --- translate/storage/xliff.py (revision 7897) +++ translate/storage/xliff.py (working copy) @@ -283,6 +283,17 @@ groups.append(pairs) #not extend return groups + def delcontextgroup(self, name): + """Removes all the context groups with the specified name""" + #XXX: I really not sure about this behavior, maybe we should remove + # only the first group with the given name + grouptags = self.xmlelement.findall( + ".//%s" % self.namespaced("context-group")) + for group in grouptags: + if group.get("name") == name: + self.xmlelement.remove(group) + # break + def getrestype(self): """returns the restype attribute in the trans-unit tag""" return self.xmlelement.get("restype") Index: translate/storage/test_xliff.py =================================================================== --- translate/storage/test_xliff.py (revision 7897) +++ translate/storage/test_xliff.py (working copy) @@ -49,6 +49,25 @@ unit.adderror(errorname='test1', errortext='New error 1.') assert unit.geterrors()['test1'] == 'New error 1.' + def test_contextgroup(self): + """tests context groups """ + unit = self.UnitClass("Group") + unit.createcontextgroup('my-group', [('group-type', 'my message')], + purpose="test context group") + groups = unit.getcontextgroups('my-group') + assert len(groups) == 1 + + # group = [(type, message)] + group = groups[0] + print group + assert group[0][0] == 'group-type' + assert group[0][1] == 'my message' + + unit.delcontextgroup('my-group') + groups = unit.getcontextgroups('my-group') + assert groups == [] + + class TestXLIFFfile(test_base.TestTranslationStore): StoreClass = xliff.xlifffile skeleton = ''' Index: translate/storage/test_pypo.py =================================================================== --- translate/storage/test_pypo.py (revision 7897) +++ translate/storage/test_pypo.py (working copy) @@ -141,6 +141,20 @@ print str(unit) assert str(unit) == expected + def test_context(self): + """test context message""" + unit = self.UnitClass("Test") + #XXX: getcontext() also returns other comments, this is will not be + # tested here + assert unit.getcontext() == '' + + unit.setcontext("test context") + assert unit.getcontext() == "test context" + + unit.setcontext("") + assert unit.getcontext() == "" + + class TestPYPOFile(test_po.TestPOFile): StoreClass = pypo.pofile def test_combine_msgidcomments(self): Index: translate/storage/pypo.py =================================================================== --- translate/storage/pypo.py (revision 7897) +++ translate/storage/pypo.py (working copy) @@ -740,6 +740,16 @@ """Get the message context.""" return unquotefrompo(self.msgctxt) + self._extract_msgidcomments() + def setcontext(self, context): + """Sets the message context. + + @param context: unescaped context message + """ + if not self.msgctxt and context: + self.msgctxt = quoteforpo(context) + else: + self.msgctxt = [] + def getid(self): """Returns a unique identifier for this unit.""" context = self.getcontext()