diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | README.md | 0 | ||||
| -rwxr-xr-x | dotstr_edit.py | 445 | ||||
| -rwxr-xr-x | format_translations.sh | 9 | ||||
| -rwxr-xr-x | gettext_templates.sh | 3 | ||||
| -rw-r--r-- | locale/de/LC_MESSAGES/dotstr_edit.po | 150 | ||||
| -rw-r--r-- | strfile.py | 30 | 
7 files changed, 639 insertions, 0 deletions
| diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cc66745 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.pyc +*.mo diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/README.md diff --git a/dotstr_edit.py b/dotstr_edit.py new file mode 100755 index 0000000..25a333e --- /dev/null +++ b/dotstr_edit.py @@ -0,0 +1,445 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import strfile +import wx +import sys, os +import locale, gettext + +from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin + +def progdir(): +	"""Get the path to the directory of this file""" +	return os.path.abspath(os.path.dirname(sys.argv[0])) + +class TransDictListCtrl(wx.ListCtrl, ListCtrlAutoWidthMixin): +	"""ListCtrl for a translation dictionary""" +	def __init__(self, parent): +		wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_VIRTUAL | wx.LC_SINGLE_SEL) +		ListCtrlAutoWidthMixin.__init__(self) +		self.InsertColumn(0, _("Identification"), width=250) +		self.InsertColumn(1, _("Text")) +		self.dict = {} +		self.update() +	 +	def update(self, onlyone=None): +		""" +		Update the list. +		 +		If onlyone is set, only the translation with the key = onlyone will be updated +		If not, evrything will be updated +		""" +		if onlyone is None: +			self.DeleteAllItems() +			self.SetItemCount(len(self.dict)) +			self.RefreshItems(0,len(self.dict)) +		else: +			key, val = onlyone +			self.dict[key] = val +			self.RefreshItem(self.dict.keys().index(key)) +	 +	def set_dict(self, d): +		"""Set the translation dictionary""" +		self.dict = d +		self.update() +	 +	def get_seclection(self): +		""" +		Get the key of the selected translation. +		 +		If no translation is selected, an empty string will be returned +		""" +		index = self.GetNextItem(-1, wx.LIST_NEXT_ALL, wx.LIST_STATE_SELECTED) +		return "" if index == -1 else self.dict.keys()[index] +	 +	def OnGetItemText(self, item, col): +		"""Basic implementation of the LC_VIRTUAL mechanism""" +		if col == 0: +			return self.dict.keys()[item] +		else: +			return self.dict.values()[item] + +class new_entry_dialog(wx.Dialog): +	""" +	Dialog that prompts the user for a new translation key +	""" +	def __init__(self, parent): +		# Layout stuff +		wx.Dialog.__init__(self, parent, title=_("New entry"), size=(500,-1)) +		 +		vbox = wx.BoxSizer(wx.VERTICAL) +		vbox.Add(wx.StaticText(self, label=_("Name of your new entry:")), 0, wx.EXPAND | wx.ALL, 5) +		 +		hbox = wx.BoxSizer(wx.HORIZONTAL) +		self.part1 = wx.TextCtrl(self) +		self.part2 = wx.TextCtrl(self) +		hbox.Add(self.part1, 2, wx.EXPAND, 0) +		hbox.Add(wx.StaticText(self, label=":"), 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.LEFT, 5) +		hbox.Add(self.part2, 3, wx.EXPAND, 0) +		hbox.SetMinSize((500,-1)) +		vbox.Add(hbox, 0, wx.EXPAND | wx.ALL, 5) +		vbox.Add(self.CreateButtonSizer(wx.OK | wx.CANCEL), 0, wx.EXPAND | wx.ALL, 5) +		 +		self.SetSizer(vbox) +		vbox.Fit(self) +		 +		self.Bind(wx.EVT_BUTTON, self.on_ok,     id=wx.OK) +		self.Bind(wx.EVT_BUTTON, self.on_cancel, id=wx.CANCEL) +		self.Bind(wx.EVT_CLOSE,  self.on_cancel) +	 +	def get_identifier(self): +		""" +		This will return the key/identifier. +		""" +		allowed_chars = map(chr, range(ord("A"), ord("Z")+1) + range(ord("a"), ord("z")+1))+["_","-"] +		part1 = "".join(filter(lambda c: c in allowed_chars, self.part1.GetValue())) +		part2 = "".join(filter(lambda c: c in allowed_chars, self.part2.GetValue())) +		 +		return part1 + ":" + part2 +	 +	def on_ok(self, event): +		self.EndModal(wx.ID_OK) +	 +	def on_cancel(self, event): +		self.EndModal(wx.ID_CANCEL) + +class editor_frame(wx.Frame): +	""" +	The Frame of the editor. +	""" +	def __init__(self): +		filter_label = _("&Filter") +		self.dict = {} +		self.changed = False +		self.filename = "" +		 +		# GUI stuff +		the_arts = wx.ArtProvider() +		wx.Frame.__init__(self, None, title=_(".str Editor"), size=(500,600)) +		 +		# menubar +		menubar = wx.MenuBar() +		 +		m_file = wx.Menu() +		m_file.AppendItem(wx.MenuItem(m_file, wx.ID_NEW, _("&New"))) +		m_file.AppendItem(wx.MenuItem(m_file, wx.ID_OPEN, _("&Open"))) +		m_file.AppendItem(wx.MenuItem(m_file, wx.ID_SEPARATOR)) +		m_file.AppendItem(wx.MenuItem(m_file, wx.ID_SAVE, _("&Save"))) +		m_file.AppendItem(wx.MenuItem(m_file, wx.ID_SAVEAS, _("Save &As"))) +		m_file.AppendItem(wx.MenuItem(m_file, wx.ID_SEPARATOR)) +		m_file.AppendItem(wx.MenuItem(m_file, wx.ID_EXIT, _("&Exit"))) +		 +		m_help = wx.Menu() +		m_help.AppendItem(wx.MenuItem(m_help, wx.ID_ABOUT, _("&About"))) +		 +		menubar.Append(m_file, _("&File")) +		menubar.Append(m_help, _("&Help")) +		 +		self.SetMenuBar(menubar) +		 +		# toolbar +		toolbar = self.CreateToolBar() +		toolbar.AddLabelTool(wx.ID_NEW, _("New"), the_arts.GetBitmap(wx.ART_NEW, wx.ART_TOOLBAR)) +		toolbar.AddLabelTool(wx.ID_OPEN, _("Open"), the_arts.GetBitmap(wx.ART_FILE_OPEN, wx.ART_TOOLBAR)) +		toolbar.AddLabelTool(wx.ID_SAVE, _("Save"), the_arts.GetBitmap(wx.ART_FILE_SAVE, wx.ART_TOOLBAR)) +		toolbar.Realize() +		 +		# shortcuts +		jump_to_filter_id = wx.NewId() +		filter_shortcut_char = ord(filter_label[filter_label.find("&")+1].lower()) +		shortcuts = wx.AcceleratorTable([ +			(wx.ACCEL_CTRL, ord('s'), wx.ID_SAVE), +			(wx.ACCEL_CTRL, ord('o'), wx.ID_OPEN), +			(wx.ACCEL_CTRL, ord('n'), wx.ID_NEW), +			(wx.ACCEL_CTRL, ord('q'), wx.ID_EXIT), +			(wx.ACCEL_CTRL, filter_shortcut_char, jump_to_filter_id) +		]) +		self.SetAcceleratorTable(shortcuts) +		 +		# the "real" GUI +		self.mainpanel = wx.Panel(self, -1) +		vbox = wx.BoxSizer(wx.VERTICAL) +		 +		filter_hbox = wx.BoxSizer(wx.HORIZONTAL) +		self.input_filter = wx.TextCtrl(self.mainpanel) +		filter_hbox.Add(wx.StaticText(self.mainpanel, label=filter_label), 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 5) +		filter_hbox.Add(self.input_filter, 1, wx.EXPAND, 0) +		vbox.Add(filter_hbox, 0, wx.EXPAND | wx.ALL, 5) +		 +		trl_hbox = wx.BoxSizer(wx.HORIZONTAL) +		self.transl_list = TransDictListCtrl(self.mainpanel) +		 +		trl_vbox = wx.BoxSizer(wx.VERTICAL) +		trl_add_btn = wx.BitmapButton(self.mainpanel, bitmap=the_arts.GetBitmap(wx.ART_ADD_BOOKMARK, wx.ART_BUTTON)) +		trl_del_btn = wx.BitmapButton(self.mainpanel, bitmap=the_arts.GetBitmap(wx.ART_DEL_BOOKMARK, wx.ART_BUTTON)) +		trl_vbox.Add(trl_add_btn, 0, wx.EXPAND | wx.BOTTOM, 5) +		trl_vbox.Add(trl_del_btn, 0, wx.EXPAND, 0) +		 +		trl_hbox.Add(self.transl_list, 1, wx.EXPAND, wx.RIGHT, 5) +		trl_hbox.Add(trl_vbox, 0, wx.EXPAND, 0) +		vbox.Add(trl_hbox, 3, wx.EXPAND | wx.ALL, 5) +		 +		vbox.Add(wx.StaticLine(self.mainpanel, style=wx.LI_HORIZONTAL),.0, wx.EXPAND | wx.ALL, 5) +		 +		vbox.Add(wx.StaticText(self.mainpanel, label=_("Text:")), 0, wx.EXPAND | wx.ALL, 5) +		self.trans_text_ctrl = wx.TextCtrl(self.mainpanel, style=wx.TE_MULTILINE) +		vbox.Add(self.trans_text_ctrl, 2, wx.EXPAND | wx.ALL, 5) +		 +		self.mainpanel.SetSizer(vbox) +		 +		# Binding events +		self.Bind(wx.EVT_MENU,   self.on_new,        id=wx.ID_NEW) +		self.Bind(wx.EVT_MENU,   self.on_open,       id=wx.ID_OPEN) +		self.Bind(wx.EVT_MENU,   self.on_save,       id=wx.ID_SAVE) +		self.Bind(wx.EVT_MENU,   self.on_saveas,     id=wx.ID_SAVEAS) +		self.Bind(wx.EVT_MENU,   self.on_close,      id=wx.ID_EXIT) +		self.Bind(wx.EVT_MENU,   self.on_about,      id=wx.ID_ABOUT) +		self.Bind(wx.EVT_TEXT,   self.on_filter,     id=self.input_filter.GetId()) +		self.Bind(wx.EVT_TEXT,   self.on_textedit,   id=self.trans_text_ctrl.GetId()) +		self.Bind(wx.EVT_BUTTON, self.on_add,        id=trl_add_btn.GetId()) +		self.Bind(wx.EVT_BUTTON, self.on_del,        id=trl_del_btn.GetId()) +		self.Bind(wx.EVT_MENU,   self.on_jmp_filter, id=jump_to_filter_id) +		self.Bind(wx.EVT_CLOSE,  self.on_close) +		self.Bind(wx.EVT_LIST_ITEM_SELECTED,   self.on_listsel,   id=self.transl_list.GetId()) +		self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.on_listunsel, id=self.transl_list.GetId()) +		 +	def really_discard(self): +		""" +		If the content was modified, the user will be asked if he really wants to discard the changes +		 +		This will return True if the calling function can continue normal work. +		""" +		if self.changed: +			dialog = wx.MessageDialog(None, +			                          message=_("You did not save your changes. Continue?"), +			                          caption=_("Unsaved changes"), +			                          style=wx.ICON_QUESTION | wx.YES_NO) +			user_ret = dialog.ShowModal() +			dialog.Destroy() +			return user_ret == wx.ID_YES +		return True +	 +	def populate_list(self, autoselect=None): +		""" +		Populating the translation list with the filtered self.dict +		 +		If autoselect is not None, the given translation will be selected and focussed. +		""" +		filter_str = self.input_filter.GetValue().lower() +		f_dict = {} +		for key in self.dict.iterkeys(): +			if filter_str != '': +				if (filter_str not in key.lower()) and (filter_str not in self.dict[key].lower()): +					continue +			f_dict[key] = self.dict[key] +		self.transl_list.set_dict(f_dict) +		self.trans_text_ctrl.SetValue("") +		if autoselect is not None: +			self.transl_list.Select(f_dict.keys().index(autoselect)) +			self.transl_list.Focus(f_dict.keys().index(autoselect)) +	 +	def form_init(self): +		""" +		IInitializes / clears all formulars +		""" +		self.populate_list() +		self.input_filter.SetValue("") +	 +	def on_close(self, event): +		if self.really_discard(): +			self.Destroy() +	 +	def on_new(self, event): +		if self.really_discard(): +			self.dict = {} +			self.changed = False +			self.filename = "" +			self.form_init() +	 +	def on_open(self, event): +		if self.really_discard(): +			new_fn = "" +			dialog = wx.FileDialog(None, _("Choose a file"), wildcard=fd_wildcard, style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) +			if dialog.ShowModal() == wx.ID_OK: +				new_fn = dialog.GetPath() +			dialog.Destroy() +			 +			if new_fn != "": +				try: +					fp = open(new_fn, "rb") +					temp_dict = strfile.dict_parse(fp.read()) +					self.dict = temp_dict +					fp.close() +					self.filename = new_fn +					self.changed = False +					self.form_init() +				except: +					del dialog +					dialog = wx.MessageDialog(None, +					                          message=_("Could not open file.\nUsually that means that the file is invalid or you do not have enough privileges."), +					                          caption=_("Could not open file"), +					                          style=wx.ICON_ERROR | wx.OK) +					dialog.ShowModal() +					dialog.Destroy() +	 +	def save_file(self, force_path=False): +		saveto = "" +		if force_path or self.filename=='': +			if self.filename == "": +				dialog = wx.FileDialog(None, +				                       message=_("Save to"), +				                       wildcard=fd_wildcard, +				                       style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) +			else: +				def_dir, def_file = os.path.split(self.filename) +				dialog = wx.FileDialog(None, +				                       message=_("Save to"), +				                       wildcard=fd_wildcard, +				                       defaultDir=def_dir, +				                       defaultFile=def_file, +				                       style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) +			if dialog.ShowModal() == wx.ID_OK: +				saveto = dialog.GetPath() +			else: +				saveto = "" +			dialog.Destroy() +		else: +			saveto = self.filename +		if saveto != "": +			try: +				fp = open(saveto, "w") +				strfile.dict_gen(self.dict, fp) +				fp.close() +			except: +				err_dialog = wx.MessageDialog( +					None, +					message=_("Can not write to file \"%s\".\nUsually that means that you do not have enough privileges or you ran out of disc memory.") % saveto, +					caption=_("Can not save file."), +					style=wx.ICON_ERROR | wx.OK) +				err_dialog.ShowModal() +				err_dialog.Close() +			self.changed = False +	 +	def on_save(self, event): +		self.save_file() +	 +	def on_saveas(self, event): +		self.save_file(True) +	 +	def on_about(self, event): +		description = _(".str Editor is a tool for editing the .str files of EA's BFME2") +		licence = u"""Copyright (c) 2010-2011 \"Die Völker Mittelerdes\" Modding Crew + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.""" +		info = wx.AboutDialogInfo() +		info.SetName(_('.str Editor')) +		info.SetVersion('0.1') +		info.SetDescription(description) +		info.SetCopyright(u'(C) 2010-2011 \"Die Völker Mittelerdes\" Modding Crew') +		info.SetLicence(licence) +		info.AddDeveloper('Kevin Chabowski') +		 +		wx.AboutBox(info) +	 +	def on_listsel(self, event): +		self.trans_text_ctrl.SetValue(strfile.unescape(self.dict[self.transl_list.get_seclection()])) +	 +	def on_listunsel(self, event): +		self.trans_text_ctrl.SetValue("") +	 +	def on_filter(self, event): +		if self.input_filter.GetValue() != "": +			self.populate_list() +		if len(self.transl_list.dict) == 0 and self.input_filter.GetValue() != "": +			self.input_filter.SetBackgroundColour(wx.Colour(255,100,100)) +		else: +			self.input_filter.SetBackgroundColour(wx.NullColour) +	 +	def on_textedit(self, event): +		key = self.transl_list.get_seclection() +		if key != "": +			newval = strfile.escape(self.trans_text_ctrl.GetValue()) +			self.dict[key] = newval +			self.transl_list.update((key, newval)) +			self.changed = True +	 +	def on_add(self, event): +		addthis = ":" +		while addthis == ":": +			dialog = new_entry_dialog(None) +			if dialog.ShowModal() != wx.ID_OK: +				dialog.Destroy() +				return +			addthis = dialog.get_identifier() +			dialog.Destroy() +			if addthis in self.dict.keys(): +				addthis = ':' +				del dialog +				dialog = wx.MessageDialog( +					None, +					message=_("This name is already in use. Choose another one."), +					caption=_("Invalid name"), +					style=wx.ICON_WARNING | wx.OK +				) +				dialog.ShowModal() +				dialog.Destroy() +			del dialog +		self.changed = True +		self.dict[addthis] = "" +		self.input_filter.SetValue("") +		self.populate_list(addthis) +		 +	 +	def on_del(self, event): +		delthis =  self.transl_list.get_seclection() +		if delthis != "": +			del self.dict[delthis] +			self.changed = True +			self.populate_list() +	 +	def on_jmp_filter(self, event): +		self.input_filter.SetFocus() + +class dotstr_edit_app(wx.App): +	def OnInit(self): +		app_frame = editor_frame() +		app_frame.Show() +		self.SetTopWindow(app_frame) +		return True + +if __name__ == '__main__': +	# init localisation +	if os.name == 'nt':  +		# windows hack for locale setting  +		lang = os.getenv('LANG')  +		if lang is None:  +			default_lang, default_enc = locale.getdefaultlocale()  +			if default_lang:  +				lang = default_lang  +		if lang:  +			os.environ['LANG'] = lang +	locale.setlocale(locale.LC_ALL, '') +	translator = gettext.translation('dotstr_edit', os.path.join(progdir(), 'locale'), fallback=True) +	translator.install(True) +	 +	fd_wildcard = _("str File")+"|*.str|*.*|*.*" +	 +	# Start application +	app = dotstr_edit_app() +	app.MainLoop() + diff --git a/format_translations.sh b/format_translations.sh new file mode 100755 index 0000000..f0c4536 --- /dev/null +++ b/format_translations.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +for locale_dir in locale/*; do +	for pofile in $locale_dir/LC_MESSAGES/*.po; do +		mofile=`echo $pofile | sed -n "s/\\.po/\\.mo/p"`;	 +		echo "$pofile => $mofile"; +		msgfmt "$pofile" -o "$mofile"; +	done; +done; diff --git a/gettext_templates.sh b/gettext_templates.sh new file mode 100755 index 0000000..dc28cab --- /dev/null +++ b/gettext_templates.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +xgettext -d dotstr_edit -s -L Python -o dotstr_edit.pot dotstr_edit.py diff --git a/locale/de/LC_MESSAGES/dotstr_edit.po b/locale/de/LC_MESSAGES/dotstr_edit.po new file mode 100644 index 0000000..6d20941 --- /dev/null +++ b/locale/de/LC_MESSAGES/dotstr_edit.po @@ -0,0 +1,150 @@ +# German translations for sum package. +# Copyright (C) 2010 THE sum'S COPYRIGHT HOLDER +# This file is distributed under the same license as the sum package. +# Automatically generated, 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: sum 2tools\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-11-28 00:57+0100\n" +"PO-Revision-Date: 2010-11-28 01:10+0100\n" +"Last-Translator: Kevin Chabowski <kevin@kch42.de>\n" +"Language-Team: none\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: dotstr_edit.py:132 +msgid "&About" +msgstr "&Über" + +#: dotstr_edit.py:129 +msgid "&Exit" +msgstr "S&chließen" + +#: dotstr_edit.py:134 +msgid "&File" +msgstr "&Datei" + +#: dotstr_edit.py:110 +msgid "&Filter" +msgstr "&Filter" + +#: dotstr_edit.py:135 +msgid "&Help" +msgstr "&Hilfe" + +#: dotstr_edit.py:123 +msgid "&New" +msgstr "&Neu" + +#: dotstr_edit.py:124 +msgid "&Open" +msgstr "&Öffnen" + +#: dotstr_edit.py:126 +msgid "&Save" +msgstr "&Speichern" + +#: dotstr_edit.py:117 +#: dotstr_edit.py:335 +msgid ".str Editor" +msgstr ".str Editor" + +#: dotstr_edit.py:332 +msgid ".str Editor is a tool for editing the .str files of EA's BFME2" +msgstr ".str Editor ist ein Tool zum bearbeiten der .str Dateien von EA's SuM2" + +#: dotstr_edit.py:319 +msgid "Can not save file." +msgstr "Kann Datei nicht speichern." + +#: dotstr_edit.py:318 +#, python-format +msgid "" +"Can not write to file \"%s\".\n" +"Usually that means that you do not have enough privileges or you ran out of disc memory." +msgstr "" +"Kann nicht auf Datei \"%s\" schreiben.\n" +"Normalerweise bedeutet dies, dass du nicht genügend Privilegien oder nicht genug Speicherplatz hast." + +#: dotstr_edit.py:264 +msgid "Choose a file" +msgstr "Wähle Datei aus" + +#: dotstr_edit.py:282 +msgid "Could not open file" +msgstr "Kann Datei nicht öffnen" + +#: dotstr_edit.py:281 +msgid "" +"Could not open file.\n" +"Usually that means that the file is invalid or you do not have enough privileges." +msgstr "" +"Kann Datei nicht öffnen.\n" +"Normalerweise bedeutet dies, dass du nicht genügend Privilegien hast." + +#: dotstr_edit.py:20 +msgid "Identification" +msgstr "Identifikation" + +#: dotstr_edit.py:381 +msgid "Invalid name" +msgstr "Ungültiger Name" + +#: dotstr_edit.py:70 +msgid "Name of your new entry:" +msgstr "Name deines neuen Eintrages:" + +#: dotstr_edit.py:141 +msgid "New" +msgstr "Neu" + +#: dotstr_edit.py:67 +msgid "New entry" +msgstr "Neuer Eintrag" + +#: dotstr_edit.py:142 +msgid "Open" +msgstr "Öffnen" + +#: dotstr_edit.py:143 +msgid "Save" +msgstr "Speichern" + +#: dotstr_edit.py:127 +msgid "Save &As" +msgstr "Spechern &unter" + +#: dotstr_edit.py:292 +#: dotstr_edit.py:298 +msgid "Save to" +msgstr "Spechern unter" + +#: dotstr_edit.py:21 +msgid "Text" +msgstr "Text" + +#: dotstr_edit.py:183 +msgid "Text:" +msgstr "Text:" + +#: dotstr_edit.py:380 +msgid "This name is already in use. Choose another one." +msgstr "Dieser Name wird bereits benutzt. Wähle einen anderen." + +#: dotstr_edit.py:214 +msgid "Unsaved changes" +msgstr "Ungespeicherte Änderungen" + +#: dotstr_edit.py:213 +msgid "You did not save your changes. Continue?" +msgstr "Du hast deine Änderungen nicht gespeichert. Fortfahren?" + +#: dotstr_edit.py:425 +msgid "str File" +msgstr "str Datei" + diff --git a/strfile.py b/strfile.py new file mode 100644 index 0000000..b70e8c4 --- /dev/null +++ b/strfile.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os, re + +lotr_str_regex = re.compile(r'([A-Z]*\:.*?)\"(.*?)\"(?:.*?)END',re.DOTALL) + +def dict_parse(rawdata): +	global lotr_str_regex +	rawdata = rawdata.decode("latin-1") +	 +	dictionary = {} +	 +	for match, string in lotr_str_regex.findall(rawdata): +		match = match.strip() +		string = string.strip() +		 +		dictionary[match] = string +	return dictionary + +def dict_gen(dictionary, fp): +	for match in dictionary: +		fp.write("%s\n\"%s\"\nEND\n\n" % (match.encode('latin-1'), +		                              dictionary[match].encode('latin-1'))) + +def escape(text): +	return text.replace("\n", "\\n") + +def unescape(text): +	return text.replace("\\n", "\n") | 
