Index: translate/storage/base.py =================================================================== --- translate/storage/base.py (revision 7770) +++ translate/storage/base.py (working copy) @@ -64,9 +64,13 @@ source code this unit came from. - Zero or more I{errors}. Some tools (eg. L{pofilter }) can run checks on translations and produce error messages. + - Zero or one I{prev_source} string, the old version of the translatable text. + - Zero or one I{prev_context} string, the old version of the message context. @group Source: *source* @group Target: *target* + @group PrevSource: *PrevSource* + @group PrevContext: *PrevContext* @group Notes: *note* @group Locations: *location* @group Errors: *error* @@ -77,6 +81,8 @@ self.source = source self.target = None + self.prev_source = None + self.prev_context = None self.notes = "" super(TranslationUnit, self).__init__() @@ -290,6 +296,30 @@ """This unit in a list.""" return [self] + def setprev_source(self, source): + """Sets the previous source message for this unit""" + self.prev_source = source + + def getprev_source(self): + """Gets the previous source message for this unit""" + return self.prev_source + + def setprev_context(self, context): + """Sets the previous context of this unit""" + self.prev_context = context + + def getprev_context(self): + """Gets the previous context of this unit""" + return self.prev_context + + def set_as_previous(self): + """Sets this unit as a previous unit message""" + if self.isfuzzy(): + return + self.setprev_context(self.getcontext()) + self.setprev_source(self.source) + self.markfuzzy() + def buildfromunit(cls, unit): """Build a native unit from a foreign unit, preserving as much information as possible.""" Index: translate/storage/test_base.py =================================================================== --- translate/storage/test_base.py (revision 7770) +++ translate/storage/test_base.py (working copy) @@ -126,6 +126,32 @@ actual_notes = unit.getnotes() assert actual_notes == expected_notes + def test_prev_source(self): + unit = self.UnitClass("Test") + assert not unit.prev_source + + unit.setprev_source("Tested") + assert unit.prev_source == "Tested" + + unit.setprev_source("") + assert not unit.prev_source + + def test_prev_context(self): + unit = self.UnitClass("Test ") + assert not unit.prev_context + + unit.setprev_context("Tested Context") + assert unit.prev_context == "Tested Context" + + unit.setprev_context("") + assert not unit.prev_context + + def test_set_as_previous(self): + unit = self.UnitClass("Test") + unit.set_as_previous() + assert unit.prev_source == "Test" + + class TestTranslationStore: """Tests a TranslationStore. Derived classes can reuse these tests by pointing StoreClass to a derived Store""" Index: translate/storage/cpo.py =================================================================== --- translate/storage/cpo.py (revision 7770) +++ translate/storage/cpo.py (working copy) @@ -134,12 +134,18 @@ gpo.po_message_msgid_plural.restype = STRING gpo.po_message_msgstr.restype = STRING gpo.po_message_msgstr_plural.restype = STRING +gpo.po_message_prev_msgid.restype = STRING +gpo.po_message_prev_msgid.restype = STRING +gpo.po_message_prev_msgid_plural.restype = STRING # Message (set methods) gpo.po_message_set_comments.argtypes = [c_int, STRING] gpo.po_message_set_extracted_comments.argtypes = [c_int, STRING] gpo.po_message_set_fuzzy.argtypes = [c_int, c_int] gpo.po_message_set_msgctxt.argtypes = [c_int, STRING] +gpo.po_message_set_prev_msgctxt.argtypes = [c_int, STRING] +gpo.po_message_set_prev_msgid.argtypes = [c_int, STRING] +gpo.po_message_set_prev_msgid_plural.argtypes = [c_int, STRING] # Setup the po_xerror_handler xerror_handler = po_xerror_handler() @@ -181,6 +187,70 @@ gpo.po_message_set_msgid_plural(self._gpo_message, msgid_plural) msgid_plural = property(None, setmsgid_plural) + def setprev_context(self, msgid_context): + """Set the previous context for this message""" + if self.isfuzzy(): + return + gpo.po_message_set_prev_msgctxt(self._gpo_message, msgid_context) + + def getprev_context(self): + """Get the previous context for this message, if any """ + prev_ctxt = gpo.po_message_prev_msgctxt(self._gpo_message) + if not prev_ctxt: + return "" + return prev_ctxt + + prev_context = property(getprev_context, setprev_context) + + def setprev_source(self, prev_source): + """Set msgid as a previous msgid for this message""" + if self.isfuzzy(): + return + if isinstance(prev_source, multistring): + prev_source = prev_source.strings + if isinstance(prev_source, unicode): + prev_source = prev_source.encode(self._encoding) + if isinstance(prev_source, list): + if len(prev_source) > 1: + msgid_plural = str(prev_source[1]) + if isinstance(msgid_plural, list): + msgid_plural = "".join(msgid_plural) + + gpo.po_message_set_prev_msgid_plural(self._gpo_message, + msgid_plural) + prev_source = str(prev_source[0]) + + self.source = "" + gpo.po_message_set_prev_msgid(self._gpo_message, prev_source) + + def getprev_source(self): + """Get the previous msgid for this message, if any""" + prev_source = gpo.po_message_prev_msgid(self._gpo_message) + if not prev_source: + return multistring(u"") + + prev_source = multistring(prev_source, self._encoding) + prev_plural = gpo.po_message_prev_msgid_plural(self._gpo_message) + if prev_plural: + prev_source.strings.append(prev_plural.decode(self._encoding)) + return prev_source + + prev_source = property(getprev_source, setprev_source) + + def set_as_previous(self): + """Sets the current msgid as previous message. Then, the current + msgid could be filled with a new msgid. Note that, if a unit + contains a previous msgid, it also is marked as fuzzy (to keep the + same behavior as msgmerge). + """ + if not self.target: + return + + # the 'pure' context string + self.prev_context = gpo.po_message_msgctxt(self._gpo_message) + self.prev_source = self.source + self.markfuzzy() + def getsource(self): def remove_msgid_comments(text): if not text: Index: translate/storage/test_cpo.py =================================================================== --- translate/storage/test_cpo.py (revision 7770) +++ translate/storage/test_cpo.py (working copy) @@ -72,6 +72,79 @@ unit.addnote("# Double commented comment") assert unit.getnotes() == "# Double commented comment" + def test_previous_source(self): + """tests if we handle previous msgid properly""" + unit = self.UnitClass("Cat") + assert unit.prev_source == "" + assert isinstance(unit.prev_source, multistring) + + unit.prev_source = "Feline" + assert unit.prev_source == "Feline" + assert isinstance(unit.prev_source, multistring) + + unit.prev_source = ["Feline", "Felines"] + assert unit.prev_source.strings == ["Feline", "Felines"] + assert unit.prev_source == "Feline" + assert isinstance(unit.prev_source, multistring) + + unit.prev_source = "" + assert unit.prev_source == "" + assert len(unit.prev_source.strings) == 1 + assert isinstance(unit.prev_source, multistring) + + unit.markfuzzy() + unit.prev_source = "Feline" + assert unit.prev_source == "" + assert len(unit.prev_source.strings) == 1 + assert isinstance(unit.prev_source, multistring) + + def test_previous_context(self): + """tests if we handle previous context messages properly""" + unit = self.UnitClass("Cat") + assert unit.prev_context == "" + + context = "A sort of a cute animal" + unit.prev_context = context + assert unit.prev_context == context + + unit.prev_context = "" + assert unit.prev_context == "" + + unit.markfuzzy() + unit.prev_context = "A sort of a cute animal" + assert unit.prev_context == "" + + def test_set_as_previous(self): + """tests if we set previous messages properly""" + # This is just a sanity test, for a more complete test look + # at convert/test_pot2po.py + unit = self.UnitClass("Test %d") + unit.msgid_plural = ["Tests %d"] + unit.target = ["Teste %d", "Testes %d"] + unit.set_as_previous() + unit.source = "Test %s" + test_unit = '''#, fuzzy\n#| msgid "Test %d"\n#| msgid_plural "Tests %d" +msgid "Test %s"\nmsgstr "Teste %d"\n''' + assert str(unit) == test_unit + assert unit.isfuzzy() + + # without a target, the unit remain the same + unit2 = self.UnitClass("Other") + unit2.msgid_plural = ["Others"] + expected = str(unit2) + unit2.set_as_previous() + assert str(unit2) == expected + + # we can't set a message as previous if the message is marked as fuzzy + unit = self.UnitClass("Pizza") + unit.msgid_plural = ["Pizzas"] + unit.target = ["Pizza", "Pizzas"] + unit.markfuzzy() + unit.set_as_previous() + assert unit.prev_context == "" + assert unit.prev_source == "" + + class TestCPOFile(test_po.TestPOFile): StoreClass = cpo.pofile def test_msgidcomments(self):