diff -Nru quickly-11.12/data/templates/ubuntu-application/create.py quickly-12.03/data/templates/ubuntu-application/create.py --- quickly-11.12/data/templates/ubuntu-application/create.py 2011-12-15 19:48:28.000000000 +0000 +++ quickly-12.03/data/templates/ubuntu-application/create.py 2012-03-05 17:08:32.000000000 +0000 @@ -107,12 +107,12 @@ bzr_instance.wait() bzr_instance = subprocess.Popen(["bzr", "commit", "-m", "Initial project creation with Quickly!"], stderr=subprocess.PIPE) +env = os.environ.copy() # Compile schema if present schemapath = os.path.abspath("data/glib-2.0/schemas") if os.path.exists(schemapath): subprocess.call(["glib-compile-schemas", schemapath]) - env = os.environ.copy() datadir = os.path.abspath("data") if 'XDG_DATA_DIRS' in env: env['XDG_DATA_DIRS'] = "%s:%s" % (datadir, env['XDG_DATA_DIRS']) diff -Nru quickly-11.12/data/templates/ubuntu-application/help/code/JottyWindow.py quickly-12.03/data/templates/ubuntu-application/help/code/JottyWindow.py --- quickly-11.12/data/templates/ubuntu-application/help/code/JottyWindow.py 2011-12-15 19:48:28.000000000 +0000 +++ quickly-12.03/data/templates/ubuntu-application/help/code/JottyWindow.py 2012-03-14 23:23:36.000000000 +0000 @@ -7,6 +7,8 @@ from gettext import gettext as _ gettext.textdomain('jotty') +import os +from gi.repository import GLib # pylint: disable=E0611 from gi.repository import Gtk # pylint: disable=E0611 import logging logger = logging.getLogger('jotty') @@ -15,16 +17,11 @@ from jotty.AboutJottyDialog import AboutJottyDialog from jotty.PreferencesJottyDialog import PreferencesJottyDialog -from desktopcouch.records.server import CouchDatabase -from desktopcouch.records.record import Record - -# pylint: disable=E1002,E1101 - # See jotty_lib.Window.py for more details about how this class works class JottyWindow(Window): __gtype_name__ = "JottyWindow" - def finish_initializing(self, builder): + def finish_initializing(self, builder): # pylint: disable=E1002 """Set up the main window""" super(JottyWindow, self).finish_initializing(builder) @@ -32,7 +29,6 @@ self.PreferencesDialog = PreferencesJottyDialog # Code for other initialization actions should be added here. - self.database = CouchDatabase("jotty", create=True) def on_mnu_save_activate(self, widget, data=None): #get the title for the note @@ -42,38 +38,32 @@ buff = self.ui.textview1.get_buffer() start_iter = buff.get_start_iter() end_iter = buff.get_end_iter() - text = buff.get_text(start_iter,end_iter) + text = buff.get_text(start_iter, end_iter, True) - #get all the records - record_type = "http://wiki.ubuntu.com/Quickly/JottyDoc" - results = self.database.get_records(record_type = record_type, create_view = True) - - #update a record that has the same title - for result in results: - document = result.value - if document["title"] == title: - key = document["_id"] - self.database.update_fields(key, {"text":text}) - return - - #if no records had the title, create it - new_rec = Record({"record_type":record_type, "title":title, "text":text}) - self.database.put_record(new_rec) + #create the filename + data_dir = GLib.get_user_data_dir() + jotty_dir = os.path.join(data_dir, "jotty") + filename = os.path.join(jotty_dir, title) + + #write the data + GLib.mkdir_with_parents(jotty_dir, 0o700) + GLib.file_set_contents(filename, text) def on_mnu_open_activate(self, widget, data=None): #get the name of the document to open title = self.ui.entry1.get_text() text = "" - - #get all the records - record_type = "http://wiki.ubuntu.com/Quickly/JottyDoc" - results = self.database.get_records(record_type = record_type,create_view = True) - - #get the text if there is a matching title - for result in results: - document = result.value - if document["title"] == title: - text = document["text"] + + #create the filename + data_dir = GLib.get_user_data_dir() + jotty_dir = os.path.join(data_dir, "jotty") + filename = os.path.join(jotty_dir, title) + + #try to get the data from the file if it exists + try: + success, text = GLib.file_get_contents(filename) + except Exception: + text = "" #set the UI to display the string buff = self.ui.textview1.get_buffer() diff -Nru quickly-11.12/data/templates/ubuntu-application/help/po/de.po quickly-12.03/data/templates/ubuntu-application/help/po/de.po --- quickly-11.12/data/templates/ubuntu-application/help/po/de.po 2011-12-15 20:04:36.000000000 +0000 +++ quickly-12.03/data/templates/ubuntu-application/help/po/de.po 2012-03-14 23:57:34.000000000 +0000 @@ -8,14 +8,14 @@ "Project-Id-Version: quickly\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-04-04 08:43-0400\n" -"PO-Revision-Date: 2011-04-05 03:53+0000\n" +"PO-Revision-Date: 2011-12-15 21:51+0000\n" "Last-Translator: Michael Terry \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-04-06 04:42+0000\n" -"X-Generator: Launchpad (build 12559)\n" +"X-Launchpad-Export-Date: 2011-12-16 05:26+0000\n" +"X-Generator: Launchpad (build 14523)\n" #: data/templates/ubuntu-application/help/tutorial.xml:13(firstname) msgid "Shane" @@ -2240,172 +2240,3 @@ msgstr "" "Launchpad Contributions:\n" " Michael Terry https://launchpad.net/~mterry" - -#~ msgid "2010" -#~ msgstr "2010" - -#~ msgid "Edit the User Interface in Glade" -#~ msgstr "Die Oberfläche in Glade bearbeiten" - -#, no-wrap -#~ msgid "" -#~ "\n" -#~ " def save_file(self, widget, data=None):\n" -#~ " print \"save\"\n" -#~ "\n" -#~ msgstr "" -#~ "\n" -#~ " def save_file(self, widget, data=None):\n" -#~ " print \"speichern\"\n" -#~ "\n" - -#, no-wrap -#~ msgid "" -#~ " \n" -#~ "quickly run\n" -#~ msgstr "" -#~ " \n" -#~ "quickly run\n" - -#, no-wrap -#~ msgid "" -#~ "\n" -#~ "sudo apt-get install quickly-widgets\n" -#~ msgstr "" -#~ "\n" -#~ "sudo apt-get install quickly-widgets\n" - -#, no-wrap -#~ msgid "" -#~ " \n" -#~ " self.database = CouchDatabase(\"jotty\", create=True)\n" -#~ msgstr "" -#~ " \n" -#~ " self.database = CouchDatabase(\"jotty\", create=True)\n" - -#~ msgid "" -#~ "\n" -#~ " #get the title for the note\n" -#~ " title = self.builder.get_object(\"entry1\").get_text()\n" -#~ msgstr "" -#~ "\n" -#~ " #Den Titel der Notiz erhalten\n" -#~ " title = self.builder.get_object(\"entry1\").get_text()\n" - -#~ msgid "" -#~ "\n" -#~ " #get the string\n" -#~ " buff = self.builder.get_object(\"textview1\").get_buffer()\n" -#~ " start_iter = buff.get_start_iter()\n" -#~ " end_iter = buff.get_end_iter()\n" -#~ " text = buff.get_text(start_iter,end_iter)\n" -#~ msgstr "" -#~ "\n" -#~ " #Den String erhalten\n" -#~ " buff = self.builder.get_object(\"textview1\").get_buffer()\n" -#~ " start_iter = buff.get_start_iter()\n" -#~ " end_iter = buff.get_end_iter()\n" -#~ " text = buff.get_text(start_iter,end_iter)\n" - -#, no-wrap -#~ msgid "" -#~ "\n" -#~ " record_type = \"http://wiki.ubuntu.com/Quickly/JottyDoc\"\n" -#~ " new_rec = Record({\"record_type\": record_type,\"title\":title, " -#~ "\"text\":text})\n" -#~ " self.database.put(new_rec)\n" -#~ msgstr "" -#~ "\n" -#~ " record_type = \"http://wiki.ubuntu.com/Quickly/JottyDoc\"\n" -#~ " new_rec = Record({\"record_type\": record_type,\"title\":title, " -#~ "\"text\":text})\n" -#~ " self.database.put(new_rec)\n" - -#, no-wrap -#~ msgid "" -#~ "\n" -#~ " #get all the records\n" -#~ " record_type = \"http://wiki.ubuntu.com/Quickly/JottyDoc\"\n" -#~ " results = self.database.get_records(record_type = " -#~ "record_type,create_view = True)\n" -#~ " #update a record that has the same title\n" -#~ " for result in results:\n" -#~ " document = result.value\n" -#~ " if document[\"title\"] == title:\n" -#~ " key = document[\"_id\"]\n" -#~ " self.database.update_fields(key, {\"text\":text})\n" -#~ " return\n" -#~ "\n" -#~ msgstr "" -#~ "\n" -#~ " #Alle Einträge erhalten\n" -#~ " record_type = \"http://wiki.ubuntu.com/Quickly/JottyDoc\"\n" -#~ " results = self.database.get_records(record_type = " -#~ "record_type,create_view = True)\n" -#~ " #Einen Eintrag mit selbem Titel aktualisieren\n" -#~ " for result in results:\n" -#~ " document = result.value\n" -#~ " if document[\"title\"] == title:\n" -#~ " key = document[\"_id\"]\n" -#~ " self.database.update_fields(key, {\"text\":text})\n" -#~ " return\n" -#~ "\n" - -#~ msgid "" -#~ "\n" -#~ " def save_file(self, widget, data=None): \n" -#~ " #get the title for the note \n" -#~ " title = self.builder.get_object(\"entry1\").get_text() \n" -#~ "\n" -#~ " #get the text to save \n" -#~ " buff = self.builder.get_object(\"textview1\").get_buffer() \n" -#~ " start_iter = buff.get_start_iter() \n" -#~ " end_iter = buff.get_end_iter() \n" -#~ " text = buff.get_text(start_iter,end_iter) \n" -#~ "\n" -#~ " #get all the records \n" -#~ " record_type = \"http://wiki.ubuntu.com/Quickly/JottyDoc\" \n" -#~ " results = self.database.get_records(record_type = " -#~ "record_type,create_view = True) \n" -#~ "\n" -#~ " #update a record that has the same title \n" -#~ " for result in results: \n" -#~ " document = result.value \n" -#~ " if document[\"title\"] == title: \n" -#~ " key = document[\"_id\"]\n" -#~ " self.database.update_fields(key, {\"text\":text}) \n" -#~ " return\n" -#~ " \n" -#~ " #if no records had the title, create it \n" -#~ " new_rec = Record({\"record_type\":record_type,\"title\":title, " -#~ "\"text\":text})\n" -#~ " self.database.put_record(new_rec)\n" -#~ msgstr "" -#~ "\n" -#~ " def save_file(self, widget, data=None): \n" -#~ " #Den Titel der Notiz erhalten\n" -#~ " title = self.builder.get_object(\"entry1\").get_text() \n" -#~ "\n" -#~ " #Den zu speichernden Text erhalten\n" -#~ " buff = self.builder.get_object(\"textview1\").get_buffer() \n" -#~ " start_iter = buff.get_start_iter() \n" -#~ " end_iter = buff.get_end_iter() \n" -#~ " text = buff.get_text(start_iter,end_iter) \n" -#~ "\n" -#~ " #Alle Einträge erhalten\n" -#~ " record_type = \"http://wiki.ubuntu.com/Quickly/JottyDoc\" \n" -#~ " results = self.database.get_records(record_type = " -#~ "record_type,create_view = True) \n" -#~ "\n" -#~ " #Einen Eintrag mit selbem Titel aktualisieren\n" -#~ " for result in results: \n" -#~ " document = result.value \n" -#~ " if document[\"title\"] == title: \n" -#~ " key = document[\"_id\"]\n" -#~ " self.database.update_fields(key, {\"text\":text}) \n" -#~ " return\n" -#~ " \n" -#~ " #Eintrag erstellen, falls keiner mit diesem Titel existierte\n" -#~ " new_rec = Record({\"record_type\":record_type,\"title\":title, " -#~ "\"text\":text})\n" -#~ " self.database.put_record(new_rec)\n" diff -Nru quickly-11.12/data/templates/ubuntu-application/help/po/en_GB.po quickly-12.03/data/templates/ubuntu-application/help/po/en_GB.po --- quickly-11.12/data/templates/ubuntu-application/help/po/en_GB.po 2011-12-15 20:04:36.000000000 +0000 +++ quickly-12.03/data/templates/ubuntu-application/help/po/en_GB.po 2012-03-14 23:57:34.000000000 +0000 @@ -8,14 +8,14 @@ "Project-Id-Version: quickly\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-04-04 08:43-0400\n" -"PO-Revision-Date: 2011-06-08 08:48+0000\n" -"Last-Translator: Stefan Pynappels \n" +"PO-Revision-Date: 2011-12-15 21:51+0000\n" +"Last-Translator: Michael Terry \n" "Language-Team: English (United Kingdom) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-06-09 04:38+0000\n" -"X-Generator: Launchpad (build 13168)\n" +"X-Launchpad-Export-Date: 2011-12-16 05:26+0000\n" +"X-Generator: Launchpad (build 14523)\n" #: data/templates/ubuntu-application/help/tutorial.xml:13(firstname) msgid "Shane" @@ -2961,6 +2961,3 @@ "Launchpad Contributions:\n" " James Thorrold https://launchpad.net/~jthorrold\n" " Stefan Pynappels https://launchpad.net/~stefan-pynappels" - -#~ msgid "2010" -#~ msgstr "2010" diff -Nru quickly-11.12/data/templates/ubuntu-application/help/po/es.po quickly-12.03/data/templates/ubuntu-application/help/po/es.po --- quickly-11.12/data/templates/ubuntu-application/help/po/es.po 2011-12-15 20:04:36.000000000 +0000 +++ quickly-12.03/data/templates/ubuntu-application/help/po/es.po 2012-03-14 23:57:34.000000000 +0000 @@ -8,14 +8,14 @@ "Project-Id-Version: quickly\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-04-04 08:43-0400\n" -"PO-Revision-Date: 2011-06-05 15:54+0000\n" +"PO-Revision-Date: 2011-12-15 21:51+0000\n" "Last-Translator: Monkey \n" "Language-Team: Spanish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-06-06 04:40+0000\n" -"X-Generator: Launchpad (build 12959)\n" +"X-Launchpad-Export-Date: 2011-12-16 05:26+0000\n" +"X-Generator: Launchpad (build 14523)\n" #: data/templates/ubuntu-application/help/tutorial.xml:13(firstname) msgid "Shane" @@ -2267,83 +2267,3 @@ msgstr "" "Launchpad Contributions:\n" " Monkey https://launchpad.net/~monkey-libre" - -#~ msgid "2010" -#~ msgstr "2010" - -#, no-wrap -#~ msgid "" -#~ "\n" -#~ "sudo apt-get install quickly-widgets\n" -#~ msgstr "" -#~ "\n" -#~ "sudo apt-get install quickly-widgets\n" - -#~ msgid "" -#~ "\n" -#~ "from jotty import (\n" -#~ " AboutJottyDialog, PreferencesJottyDialog, SaveDialog)\n" -#~ msgstr "" -#~ "\n" -#~ "from jotty import (\n" -#~ " AboutJottyDialog, PreferencesJottyDialog, SaveDialog)\n" - -#, no-wrap -#~ msgid "" -#~ "\n" -#~ " saver = SaveDialog.SaveDialog()\n" -#~ msgstr "" -#~ "\n" -#~ " saver = SaveDialog.SaveDialog()\n" - -#, no-wrap -#~ msgid "" -#~ "\n" -#~ " @property\n" -#~ " def selected_record_id(self):\n" -#~ " ids = self.couchgrid.selected_record_ids\n" -#~ " if len(ids) < 1:\n" -#~ " return None\n" -#~ " else:\n" -#~ " return ids[0]\n" -#~ "\n" -#~ msgstr "" -#~ "\n" -#~ " @property\n" -#~ " def selected_record_id(self):\n" -#~ " ids = self.couchgrid.selected_record_ids\n" -#~ " if len(ids) < 1:\n" -#~ " return None\n" -#~ " else:\n" -#~ " return ids[0]\n" -#~ "\n" - -#~ msgid "" -#~ "\n" -#~ "from jotty import (\n" -#~ " AboutJottyDialog, PreferencesJottyDialog, SaveDialog, OpenDialog)\n" -#~ msgstr "" -#~ "\n" -#~ "from jotty import (\n" -#~ " AboutJottyDialog, PreferencesJottyDialog, SaveDialog, OpenDialog)\n" - -#~ msgid "" -#~ "opener = OpenDialog.NewODialog()\n" -#~ " result = opener.run()" -#~ msgstr "" -#~ "opener = OpenDialog.NewODialog()\n" -#~ " result = opener.run()" - -#~ msgid "and then run:" -#~ msgstr "y después ejecute:" - -#~ msgid "glade" -#~ msgstr "glade" - -#, no-wrap -#~ msgid "" -#~ "\n" -#~ "Quickly help\n" -#~ msgstr "" -#~ "\n" -#~ "Quickly help\n" diff -Nru quickly-11.12/data/templates/ubuntu-application/help/po/fr.po quickly-12.03/data/templates/ubuntu-application/help/po/fr.po --- quickly-11.12/data/templates/ubuntu-application/help/po/fr.po 2011-12-15 20:04:36.000000000 +0000 +++ quickly-12.03/data/templates/ubuntu-application/help/po/fr.po 2012-03-14 23:57:34.000000000 +0000 @@ -8,14 +8,14 @@ "Project-Id-Version: quickly\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-04-04 08:43-0400\n" -"PO-Revision-Date: 2011-04-05 03:48+0000\n" +"PO-Revision-Date: 2011-12-15 21:52+0000\n" "Last-Translator: Ptitphysik \n" "Language-Team: French \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-04-06 04:42+0000\n" -"X-Generator: Launchpad (build 12559)\n" +"X-Launchpad-Export-Date: 2011-12-16 05:26+0000\n" +"X-Generator: Launchpad (build 14523)\n" #: data/templates/ubuntu-application/help/tutorial.xml:13(firstname) msgid "Shane" @@ -2236,30 +2236,3 @@ msgstr "" "Launchpad Contributions:\n" " Ptitphysik https://launchpad.net/~amalpeyre" - -#~ msgid "2010" -#~ msgstr "2010" - -#~ msgid "" -#~ "This part 1 of the Quickly tutorial. This part is " -#~ "will introduce some key Quickly commands, editing " -#~ "a user interface in Glade, and editing code in Gedit. This part of the " -#~ "tutorial will familiarize you with these three tools, and how they work " -#~ "together with python and pygtk so that you can " -#~ "Quickly build applications." -#~ msgstr "" -#~ "Première partie du tutoriel Quickly. Cette partie " -#~ "introduit quelques commandes clés de Quickly, " -#~ "l'édition d'une interface avec Glade et l'édition du code avec Gedit. Cette " -#~ "partie du tutoriel va vous familiariser avec ces trois outils, et vous " -#~ "montrer comment construire rapidement une application en les utilisant " -#~ "conjointement avec python et pygtk." - -#~ msgid "" -#~ "This will create a jotty sub directory containing a complete directory tree " -#~ "and files for an empty python application. The command finishes by running " -#~ "the newly created empty application." -#~ msgstr "" -#~ "Cela va créer un sous-dossier jotty contenant l'arborescence de fichiers et " -#~ "de répertoires de votre application vierge en python. Cette commande se " -#~ "termine par le lancement de votre toute nouvelle application." diff -Nru quickly-11.12/data/templates/ubuntu-application/help/po/hu.po quickly-12.03/data/templates/ubuntu-application/help/po/hu.po --- quickly-11.12/data/templates/ubuntu-application/help/po/hu.po 2011-12-15 20:04:36.000000000 +0000 +++ quickly-12.03/data/templates/ubuntu-application/help/po/hu.po 2012-03-14 23:57:34.000000000 +0000 @@ -8,14 +8,14 @@ "Project-Id-Version: quickly\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-04-04 08:43-0400\n" -"PO-Revision-Date: 2011-06-01 11:08+0000\n" +"PO-Revision-Date: 2011-12-15 21:51+0000\n" "Last-Translator: Richard Somlói \n" "Language-Team: Hungarian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-06-02 04:43+0000\n" -"X-Generator: Launchpad (build 12959)\n" +"X-Launchpad-Export-Date: 2011-12-16 05:26+0000\n" +"X-Generator: Launchpad (build 14523)\n" #: data/templates/ubuntu-application/help/tutorial.xml:13(firstname) msgid "Shane" @@ -2236,8 +2236,4 @@ msgid "translator-credits" msgstr "" "Launchpad Contributions:\n" -" Krasznecz Zoltán https://launchpad.net/~krasznecz-zoltan\n" -" Richard Somlói https://launchpad.net/~ricsipontaz" - -#~ msgid "2010" -#~ msgstr "2010" +" Krasznecz Zoltán https://launchpad.net/~krasznecz-zoltan" diff -Nru quickly-11.12/data/templates/ubuntu-application/help/po/nl.po quickly-12.03/data/templates/ubuntu-application/help/po/nl.po --- quickly-11.12/data/templates/ubuntu-application/help/po/nl.po 2011-12-15 20:04:36.000000000 +0000 +++ quickly-12.03/data/templates/ubuntu-application/help/po/nl.po 2012-03-14 23:57:34.000000000 +0000 @@ -8,14 +8,14 @@ "Project-Id-Version: quickly\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-04-04 08:43-0400\n" -"PO-Revision-Date: 2011-04-05 03:47+0000\n" +"PO-Revision-Date: 2011-12-15 21:52+0000\n" "Last-Translator: Michael Terry \n" "Language-Team: Dutch \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-04-06 04:41+0000\n" -"X-Generator: Launchpad (build 12559)\n" +"X-Launchpad-Export-Date: 2011-12-16 05:26+0000\n" +"X-Generator: Launchpad (build 14523)\n" #: data/templates/ubuntu-application/help/tutorial.xml:13(firstname) msgid "Shane" @@ -2238,75 +2238,4 @@ msgid "translator-credits" msgstr "" "Launchpad Contributions:\n" -" Michael Terry https://launchpad.net/~mterry" - -#~ msgid "" -#~ "Quickly is a set of choices about writing apps " -#~ "for Ubuntu. Out of all the wonderful richness and variety of programming for " -#~ "Linux, Quickly make some very opinionated choices " -#~ "about what tools to use, and how to combine them. The criteria for these " -#~ "choices was to make it easy and fun to write and release Linux applications, " -#~ "even if it's your first time trying, but also in a way that delivers the " -#~ "full power and flexibility of the platform. One benefit of these choices, is " -#~ "that it's also easier to write tools that make it even easier and more fun. " -#~ "So Quickly is also a set of commands." -#~ msgstr "" -#~ "Quickly is een verzameling keuzes met betrekking " -#~ "tot het schrijven van Ubuntu programma's. Uit alle prachtige rijkdom en " -#~ "verscheidenheid aan programmeermiddelen voor Linux, maakt " -#~ "Quickly een aantal zeer eigenwijze keuzes over " -#~ "welke hulpmiddelen te gebruiken, en hoe ze te combineren. De criteria voor " -#~ "deze keuzes zijn het makkelijk en leuk maken om Linux-applicaties te " -#~ "schrijven en te verspreiden, zelfs al is het je eerste keer, maar ook op een " -#~ "manier die de volledige kracht en flexibiliteit van het platform levert. Een " -#~ "voordeel van deze keuzes is dat het ook eenvoudiger is om gereedschappen te " -#~ "schrijven die het nog gemakkelijker en leuker te maken. Dus " -#~ "Quickly is ook een set van commando's." - -#~ msgid "" -#~ "This part 1 of the Quickly tutorial. This part is " -#~ "will introduce some key Quickly commands, editing " -#~ "a user interface in Glade, and editing code in Gedit. This part of the " -#~ "tutorial will familiarize you with these three tools, and how they work " -#~ "together with python and pygtk so that you can " -#~ "Quickly build applications." -#~ msgstr "" -#~ "Dit is deel 1 van de Quickly cursus. Dit deel zal " -#~ "een aantal belangrijke Quickly commando's " -#~ "introduceren, het bewerken van een gebruiker interface in Glade, en het " -#~ "bewerken van code in gedit. In dit deel van de cursus maakt u kennis met " -#~ "deze drie instrumenten, en hoe ze samenwerken met Python en pygtk, zodat u " -#~ "snel applicaties kunt bouwen." - -#~ msgid "" -#~ "This will create a jotty sub directory containing a complete directory tree " -#~ "and files for an empty python application. The command finishes by running " -#~ "the newly created empty application." -#~ msgstr "" -#~ "Dit zal een jotty sub map creëren met een complete mappen boomstruktuur en " -#~ "bestanden voor een lege python applicatie. Het commando eindigt met het " -#~ "uitvoeren van het nieuwe programma." - -#~ msgid "" -#~ " They are populated and set up, and you can resize the " -#~ "window. Notice that Quickly inferred that the " -#~ "application title is \"Jotty\". Only a few of menu items do anything in the " -#~ "empty application, Help->About, Edit->Preferences, and File->Quit." -#~ msgstr "" -#~ " Ze zijn bevolkt en klaar, en u kunt het venster vergroten " -#~ "of verkleinen. Merk op dat Quickly afleidde dat " -#~ "de titel van het programma \"Jotty\" is. Slechts een paar van de menus doen " -#~ "iets in de lege toepassing, Help-> About, Edit-> Preferences, en File-> Quit." - -#~ msgid "" -#~ " Close the application by closing the window or using the " -#~ "Quit command. Since the empty application isn't installed into Ubuntu yet, " -#~ "you can't start the application from the application menu yet. To start the " -#~ "applicaton, use the terminal to first cd into the new subdirectory, and then " -#~ "use \"quickly run\" to start the program." -#~ msgstr "" -#~ " Sluit de toepassing door het sluiten van het venster of het " -#~ "gebruik van het Quit commando. Aangezien de lege toepassing nog niet in " -#~ "Ubuntu geïnstalleerd is, kunt u het nog niet starten via het start menu. Om " -#~ "de toepassing te starten gebruik je de terminal: 'cd' in de nieuwe map, en " -#~ "typ \"quickly run\"." +" Bart Willemsen https://launchpad.net/~b-willemsen8" diff -Nru quickly-11.12/data/templates/ubuntu-application/help/tutorial.xml quickly-12.03/data/templates/ubuntu-application/help/tutorial.xml --- quickly-11.12/data/templates/ubuntu-application/help/tutorial.xml 2011-12-22 14:11:33.000000000 +0000 +++ quickly-12.03/data/templates/ubuntu-application/help/tutorial.xml 2012-03-14 23:54:40.000000000 +0000 @@ -3,7 +3,7 @@ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ Quickly" > - + ] > @@ -105,15 +105,15 @@
- Now we'll add the entry field for the title and also a label for it. We'll use the top empty slot for that. First, click on "Horizontal Box" (HBox) from the "Containers" section of the toolbox, and then click on the top slot. A dialog box will open; tell it that you want two items. + Now we'll add the entry field for the title and also a label for it. We'll use the top empty slot for that. First, click on "Box" from the "Containers" section of the toolbox, and then click on the top slot. A dialog box will open; tell it that you want two items.
- The HBox is a container that arranges its contents horizontally. Add a Label to the empty left hand box, and a Text Entry to the right hand one. + A Box is a container that arranges its contents either vertically or horizontally. We want a horizontal one, so on the right bottom pane, change the "Orientation" setting to "Horizontal". Then add a Label to the empty left hand slot, and a Text Entry to the right hand one.
- Before going on, let's clean up the UI just a tad here. Select the new HBox from the list on the right. Then go to the Packing tab in the bottom right, and set Expand and Fill to "No". + Before going on, let's clean up the UI just a tad here. Select the horizontal box from the list on the right. Then go to the Packing tab in the bottom right, and set Expand and Fill to "No".
@@ -121,7 +121,7 @@
- Select the label. On the General tab, set the Label field to "Name:". Set Expand and Fill to "No" for the label, but keep them as "Yes" for the entry. Set the Padding for both to 6 (also on the Packing tab). + Select the label. On the General tab, set the Label field to "Name:". Set Expand and Fill to "No" for the label, and set them to "Yes" for the entry. Set the Padding for both to 6 (also on the Packing tab).
@@ -165,142 +165,95 @@ Implementing Save -Now we'll write a little code in the signal handler to actually save the text. Because we want it to be easy for users to do things like syncronize their Jotty documents between computers, back them up, etc... we'll use CouchDB as our backend, and we'll use desktopcouch for our API. We'll also use a widget from the Quickly Widgets library to make it really easy to use desktopcouch. -Desktopcouch and the desktopcouch records library should be installed for you already, but you may need to install Quickly Widgets. The fastest way to do this is from the terminal: - -sudo apt-get install python-quickly.widgets - -This will install the library and everything you need for the library to run. After everything is installed, you can write the code. The code will do the following: +Now we'll write a little code in the signal handler to actually save the text. This code will do the following: - Import the stuff you'll need from Quickly Widgets and desktopcouch. - - - Get a reference to the CouchDB database to save into. + Import any new modules you'll need. Get the title of the document and the text from the user interface. - Check if there is already a document with the same title, and if so overwrite it. - - - If there is not a document already, create one. + Write the file to disk. -Import the stuff you'll need from python-desktopcouch-records. -Add these import statements near the other imports at the top of the JottyWindow.py file: + +Import new modules: +Add these import statements near the other imports at the top of the JottyWindow.py file. The comment on the right is there for the benefit of the Python static code analysis tool pylint, if you happen to use it. + -from desktopcouch.records.server import CouchDatabase -from desktopcouch.records.record import Record - -Get a Reference to the Database -Desktopcouch will set up a database for us, or create a new one if it's needed. We'll use "jotty" for the name of the database. Since we want this line to run every time the JottyWindow is created, put it at the end of the finish_initializing function: - - self.database = CouchDatabase("jotty", create=True) - -Now that we have an instance-wide reference to the database, we'll add code to the on_mnu_save_activate method to run whenever the Save command is issued. +import os +from gi.repository import GLib # pylint: disable=E0611 + + + Here's the code to pull the title out of the title entry: -Add this to the on_mnu_save_activate method. +Add this to the on_mnu_save_activate method. #get the title for the note title = self.ui.entry1.get_text() + Here's the code to get pull the text out of the TextView: -In pygtk, TextView widgets have a text buffer that stores the text. So you ask the TextView for it's TextBuffer, and then you ask the TextBuffer for the text. You use iterators (iters) to determine from which part of the text buffer you want text. Since we want all the text, it's easy to just get the start and end iters. +In GTK+, TextView widgets have a text buffer that stores the text. So you ask the TextView for it's TextBuffer, and then you ask the TextBuffer for the text. You use iterators (iters) to determine from which part of the text buffer you want text. Since we want all the text, it's easy to just get the start and end iters. #get the string buff = self.ui.textview1.get_buffer() start_iter = buff.get_start_iter() end_iter = buff.get_end_iter() - text = buff.get_text(start_iter,end_iter) + text = buff.get_text(start_iter, end_iter, True) -Saving a document to CouchDB -A record in desktopcouch is essentially a Python dictionary with some extra key/value pairs to make the database work. So we can save the document to the couch database like this: + +Deciding where to save the note: +We'll store the document in the system hidden folder designated for user-specific data. It's simple enough to ask GLib where that folder is and then add a jotty subfolder. - record_type = "http://wiki.ubuntu.com/Quickly/JottyDoc" - new_rec = Record({"record_type":record_type, "title":title, "text":text}) - self.database.put_record(new_rec) - -The "record_type" field is not strictly required, but among other things, it makes it easy to fetch the documents later. By convention, we use a URL to specify the record type. This provides a place for other developers to go to read about the record type. The description only needs to be human readable. Couchdb is not a typed database, so don't expect that the url will have any kind of schema definition or anything. You can use whatever URL you want, and put whatever you want at that URL. - - -Check for a pre-existing note with the same title - -Before we just write the new document though, we have to take note of the fact that desktopcouch will allow you to create as many documents as you want with the same title. We probably don't want this, so we'll have to write a little code to check if there is already a document in CouchDB with the same title, and if there is, update that document rather than create a new one. - -In CouchDB, you don't do a lot of data processing in the database like you would with a relational database. To be most efficient, we could use the desktopcouch API to create a view in CouchDB, but it's probably simplest just to do the necessary processing on the client for now. To do this, we'll use a desktopcouch function to retrieve all of the records of a specified record type. + #create the filename + data_dir = GLib.get_user_data_dir() + jotty_dir = os.path.join(data_dir, "jotty") + filename = os.path.join(jotty_dir, title) + -To find and update documents with a matching title we will: - - - Retrieve all of the documents with the CouchDatabase.get_records function. - - - Check each of the returned records for a matching title. - - - If there is a match, update the record using the CouchDatabase.update_fields function and return. - - -This all may sound very weird, but in code, it's not quite so complicated: +Saving a document to user's disk: +GLib provides a convenience function for directly writing a string to a file. - #get all the records - record_type = "http://wiki.ubuntu.com/Quickly/JottyDoc" - results = self.database.get_records(record_type = record_type, create_view = True) - #update a record that has the same title - for result in results: - document = result.value - if document["title"] == title: - key = document["_id"] - self.database.update_fields(key, {"text":text}) - return + #write the data + GLib.mkdir_with_parents(jotty_dir, 0o700) + GLib.file_set_contents(filename, text) + So the whole function should look like this: - def on_mnu_save_activate(self, widget, data=None): - #get the title for the note - title = self.ui.entry1.get_text() - - #get the text to save - buff = self.ui.textview1.get_buffer() - start_iter = buff.get_start_iter() - end_iter = buff.get_end_iter() - text = buff.get_text(start_iter,end_iter) - - #get all the records - record_type = "http://wiki.ubuntu.com/Quickly/JottyDoc" - results = self.database.get_records(record_type = record_type, create_view = True) - - #update a record that has the same title - for result in results: - document = result.value - if document["title"] == title: - key = document["_id"] - self.database.update_fields(key, {"text":text}) - return - - #if no records had the title, create it - new_rec = Record({"record_type":record_type, "title":title, "text":text}) - self.database.put_record(new_rec) + def on_mnu_save_activate(self, widget, data=None): + #get the title for the note + title = self.ui.entry1.get_text() + + #get the string + buff = self.ui.textview1.get_buffer() + start_iter = buff.get_start_iter() + end_iter = buff.get_end_iter() + text = buff.get_text(start_iter, end_iter, True) + + #create the filename + data_dir = GLib.get_user_data_dir() + jotty_dir = os.path.join(data_dir, "jotty") + filename = os.path.join(jotty_dir, title) + + #write the data + GLib.mkdir_with_parents(jotty_dir, 0o700) + GLib.file_set_contents(filename, text) -CouchDB makes it really easy to see if your save function is working. You can just point your web browser at it and explore the database: -file:///home/your_user_name/.local/share/desktop-couch/couchdb.html -
- -
-
- -
-If you are redirected to a page that doesn't work, you probably just need to clear your browser cache and try again. + +It's easy to see if your save function is working. You can just explore the jotty data folder: +gvfs-open ~/.local/share/jotty + Implementing Open and New To open a saved document, the user will type the title of the document that they want to open in the text entry, and choose "Open" from the main menu. If there is no matching document there, it will just clear out the text view, ready for input. This is probably not too intuitive, so we'll add a dialog box for prompting the user for the title, but that's for later in the tutorial. For now, we'll just use the same text entry field. Implementing Open is essentially the reverse of Save: @@ -310,10 +263,10 @@ Add the on_mnu_open_activate method to the JottyWindow class. - Retrieve all of the documents with the CouchDatabase.get_records function. + Find all of the existing document names. - Check each of the returned records for a matching title. + Check if any have a matching title. If there is a match, pull out the text and display it in the text view. @@ -326,21 +279,23 @@ #get the name of the document to open title = self.ui.entry1.get_text() text = "" - - #get all the records - record_type = "http://wiki.ubuntu.com/Quickly/JottyDoc" - results = self.database.get_records(record_type = record_type,create_view = True) - - #get the text if there is a matching title - for result in results: - document = result.value - if document["title"] == title: - text = document["text"] + + #create the filename + data_dir = GLib.get_user_data_dir() + jotty_dir = os.path.join(data_dir, "jotty") + filename = os.path.join(jotty_dir, title) + + #try to get the data from the file if it exists + try: + success, text = GLib.file_get_contents(filename) + except Exception: + text = "" #set the UI to display the string buff = self.ui.textview1.get_buffer() buff.set_text(text) + Implement New Add the on_mnu_new_activate method to the JottyWindow class: @@ -350,8 +305,10 @@ buff = self.ui.textview1.get_buffer() buff.set_text("") + Remember to save your JottyWindow.py file. Complete JottyWindow.py file + Saving Your Work When Quickly created your application, it automatically added it to Bazaar, a source code versioning system. You can use Bazaar to roll back mistakes, see code history, compare versions, etc... Quickly has a convenience function for backing up your work: @@ -359,9 +316,11 @@ This will call bzr add and then bzr commit -m [your message] for you. + + Using Dialogs -In part 1, we created an application that can read and write text files, and persist them in the CouchDB backend. However, the application has a hideous usability flaw: the text box for specifying titles when saving and opening files is very confusing. In part 2, we'll fix that by adding a save and an open dialog. +In part 1, we created an application that can read and write text files, and persist them on the disk. However, the application has a hideous usability flaw: the text box for specifying titles when saving and opening files is very confusing. In part 2, we'll fix that by adding a save and an open dialog. Creating an Empty Dialog It's simple to add an empty, but working dialog to your project. Simply specify the name of the new dialog, and it will be added automatically. Assuming that you are in the jotty project directory: @@ -378,7 +337,7 @@
-Then add some widgets for the UI. Start with a Vertical Box (VBox) with two items. Put a label in the top, and an HBox in the bottom slot. In the HBox, add a label and a text widget, just like you did for JottyWindow in part 1. Set the padding and expand properties as well. +Then add some widgets for the UI. Start with a vertical Box with two items. Put a label in the top, and a horizontal Box in the bottom slot. In the horizontal box, add a label and a text entry, just like you did for JottyWindow in part 1. Set the expand property of the text entry to true.
@@ -391,7 +350,7 @@ return self.ui.entry1.get_text() We don't need to write any code for the OK and Cancel buttons, as they were automatically hooked up by Quickly when it created the dialog. -Before we go on to invoking the dialog, delete the HBox from the original JottyWindow that holds the text entry and label, as we won't be needing those. +Before we go on to invoking the dialog, delete the Box from the original JottyWindow that holds the text entry and label, as we won't be needing those.
@@ -438,7 +397,7 @@ saver.destroy() - if result != gtk.RESPONSE_OK: + if result != Gtk.ResponseType.OK: return @@ -453,39 +412,36 @@ title = saver.title_text saver.destroy() - if result != gtk.RESPONSE_OK: + if result != Gtk.ResponseType.OK: return - #get the text to save + #get the string buff = self.ui.textview1.get_buffer() start_iter = buff.get_start_iter() end_iter = buff.get_end_iter() - text = buff.get_text(start_iter,end_iter) + text = buff.get_text(start_iter, end_iter, True) - #get all the records - record_type = "http://wiki.ubuntu.com/Quickly/JottyDoc" - results = self.database.get_records(record_type = record_type,create_view = True) - - #update a record that has the same title - for result in results: - record = result.value - if record["title"] == title: - key = result.key - self.database.update_fields(key, {"text":text}) - return - - #if no records had the title, create it - new_rec = Record({"record_type":record_type, "title":title, "text":text}) - self.database.put_record(new_rec) + #create the filename + data_dir = GLib.get_user_data_dir() + jotty_dir = os.path.join(data_dir, "jotty") + filename = os.path.join(jotty_dir, title) + + #write the data + GLib.mkdir_with_parents(jotty_dir, 0o700) + GLib.file_set_contents(filename, text) Now when we choose save, we get the SaveDialog instead:
-Creating a Dialog with a CouchGrid -We'll use a similar approach in the Open dialog that we did with Save. However, there is one big difference, we want to provide the user with a list of documents that you could choose to open. We'll use a widget called CouchGrid, which is included in the Quickly Widgets library. +Creating a Dialog with a DictionaryGrid +We'll use a similar approach in the Open dialog that we did with Save. However, there is one big difference, we want to provide the user with a list of documents that you could choose to open. We'll use a widget called DictionaryGrid, which is included in the Quickly Widgets library. +Installing the Quickly Widgets library + +sudo apt-get install python-quickly.widgets + Create the Open Dialog quickly add dialog open @@ -495,57 +451,77 @@ quickly design -Start by adding a VBox and a label in the same manner as in the Save Dialog above. Leave an empty space in the VBox, we will use code to put the CouchGrid there. +Start by adding a vertical Box and a label in the same manner as in the Save Dialog above. Leave an empty space in the Box, we will use code to put the DictionaryGrid there.
Coding the Open Dialog -Creating and Adding a CouchGrid -It just takes a little bit of code to add a CouchGrid to the dialog. We need to: +Creating and Adding a DictionaryGrid +It just takes a little bit of code to add a DictionaryGrid to the dialog. We need to: - Import the CouchGrid class. + Import the DictionaryGrid class. + + + Get the list of jotty files. + + + Throw that list into a DictionaryGrid. - Create a CouchGrid pointing at the jotty database, and the desired record type. + Add the DictionaryGrid to the Dialog. - Add the CouchGrid to the dialog. + Create the get_selection function. -Import the CouchGrid class -CouchGrid is part of the quickly.widgets library, so we import it like this: +Import the DictionaryGrid class +Open the "OpenDialog.py" file with "quickly edit". DictionaryGrid is part of the quickly.widgets library, so we import it as below. Note we also want to import GLib and os, since we'll use some of their functions. -from quickly.widgets.couch_grid import CouchGrid +import os +from quickly.widgets.dictionary_grid import DictionaryGrid +from gi.repository import GLib # pylint: disable=E0611 -Create the CouchGrid -A CouchGrid needs to know three things: the name of the database, the name of the record type, and the name of the keys to use. "keys" is a list of fields that the widget will display, and by default will also use the same text for the heading of any columns. This set up should be done in the OpenDialog's finish_initializing function. All this is easily done in code like this: +Get the list of jotty files +First things first, we need to know the names of the existing documents. If you recall, we stored the files in the user's data directory. So we just need to list the files in that directory. This set up should be done in the OpenDialog's finish_initializing function. + + + + #get the jotty document names + data_dir = GLib.get_user_data_dir() + jotty_dir = os.path.join(data_dir, "jotty") + filenames = os.listdir(jotty_dir) + + +Throw that list into a DictionaryGrid +Now that we have a list of files, we need to massage it into the format DictionaryGrid expects. Namely, a list of dictionaries that hold header/value pairs. So we'll add a header to each filename and keep track of the full filename. - database = "jotty" - keys = ["title"] - record_type = "http://wiki.ubuntu.com/Quickly/JottyDoc" - self.couchgrid = CouchGrid(database, record_type=record_type,keys=keys) + #put them into a grid + dicts = [{'Name': x, 'File': os.path.join(jotty_dir, x)} for x in filenames] + self.grid = DictionaryGrid(dictionaries=dicts, keys=['Name']) -Add the CouchGrid to the Dialog -When we added the VBox to the dialog, we left an open space at the bottom. We'll use this by "packing" the CouchGrid into the VBox. We need to show it as well. So add the following lines to the finish_initializing function as well: + +Add the DictionaryGrid to the Dialog +When we added the vertical Box to the dialog, we left an open space at the bottom. We'll use this by "packing" the DictionaryGrid into the Box. We need to show it as well. So add the following lines to the finish_initializing function as well: - self.couchgrid.show() - self.ui.vbox1.pack_end(self.couchgrid) + #add grid to dialog + self.grid.show() + self.ui.box1.pack_end(self.grid, True, True, 0) Create the get_selection function -The dialog still needs a bit more code to work. It needs to return the user's selection, if there is one. To do this, we need to ask the CouchGrid what is selected. This is easy using the widget's selected_record_ids function. But the CouchGrid supports multiple selection, so we'll do the following: +The dialog still needs a bit more code to work. It needs to return the user's selection, if there is one. To do this, we need to ask the DictionaryGrid what is selected. This is easy using the widget's selected_rows member. But DictionaryGrid supports multiple selection, so we'll do the following: Use a decorator to define the function as a property accessor. - Get all the selected record ids. + Get all the selected rows. If none are selected, return None. @@ -558,12 +534,12 @@ @property - def selected_record_id(self): - ids = self.couchgrid.selected_record_ids - if len(ids) < 1: + def selected_file(self): + rows = self.grid.selected_rows + if len(rows) < 1: return None else: - return ids[0] + return rows[0]['Name'] Using the Open Dialog Now we want to use the Open Dialog in JottyWindow's on_mnu_open_activate method. To use it, we'll follow these steps: @@ -578,7 +554,7 @@ Run the Dialog - Get the id for the selected title + Get the filename for the selected title Destroy the dialog @@ -587,7 +563,7 @@ Check the response before proceeding - Use the id to get the record from CouchDB + Get the file contents Update the UI @@ -605,34 +581,31 @@ opener = OpenDialog() - result = opener.run() + result = opener.run() +
-Get the id for the selected title +Get the filename for the selected title Now use the property that we created to retrieve the title and text from the dialog. Don't forget to check the response type before going on. - rec_id = opener.selected_record_id + filename = opener.selected_file #close the dialog, and check whether to proceed opener.destroy() - if result != gtk.RESPONSE_OK: - return - - -Use the id to get the record from CouchDB -If nothing was selected, we'll just return. Otherwise, we'll retrieve the record from CouchDB and pull out the text for the document: - - - #get the record from CouchDB and extract the text - if rec_id == None: + if result != Gtk.ResponseType.OK: return - record = self.database.get_record(rec_id) - text = record["text"] + -Update the UI -Now just put the text into the TextView: +Get the file contents +If nothing was selected, we'll just return. Otherwise, we'll retrieve the file contents just like we did before and update the UI. That is, this code does not need to change, but is presented again here for completeness. + #try to get the data from the file if it exists + try: + success, text = GLib.file_get_contents(filename) + except Exception: + text = "" + #set the UI to display the string buff = self.ui.textview1.get_buffer() buff.set_text(text) @@ -640,23 +613,21 @@ def open_file(self, widget, data=None): - #run the open dialog + #get the name of the document to open opener = OpenDialog() result = opener.run() - - #get the record id from the dialog - rec_id = opener.selected_record_id + filename = opener.selected_file #close the dialog, and check whether to proceed opener.destroy() - if result != gtk.RESPONSE_OK: + if result != Gtk.ResponseType.OK: return - #get the record from CouchDB and extract the text - if rec_id == None: - return - record = self.database.get_record(rec_id) - text = record["text"] + #try to get the data from the file if it exists + try: + success, text = GLib.file_get_contents(filename) + except Exception: + text = "" #set the UI to display the string buff = self.ui.textview1.get_buffer() @@ -676,7 +647,7 @@ The Save command works more like "Save As". The application probably shouldn't pop up a SaveDialog every time you want to save. If it's already been saved, you probably just want to save it, but use a SaveDialog when the user choose Save As, or is saving a document for the first time. - The OpenDialog should probably return when the user double clicks on an item in the list. Try connecting to the "select-cursor-row" signal on the TreeView, and calling self.response(gtk.RESPONSE_OK) in the handler. + The OpenDialog should probably return when the user double clicks on an item in the list. Try connecting to the "select-cursor-row" signal on the TreeView, and calling self.response(Gtk.ResponseType.OK) in the handler. Perhaps the OK button in the OpenDialog should be disabled if nothing is selected. Try setting the "sensitivity" in Glade to "False" to start, and using the set_sensitive method on the OK button to adjust it as the selection changes. @@ -684,9 +655,6 @@ It would be more consistent for the Open and Close dialogs to have "Open" and "Close" for buttons instead of "OK". You can set a different type in the properties window in Glade. - - Loading every document into the open dialog is probably a bit inefficient. Perhaps storing the document id and using that to retrieve the document would be a better implementation. -
diff -Nru quickly-11.12/data/templates/ubuntu-application/internal/packaging.py quickly-12.03/data/templates/ubuntu-application/internal/packaging.py --- quickly-11.12/data/templates/ubuntu-application/internal/packaging.py 2011-11-01 16:48:06.000000000 +0000 +++ quickly-12.03/data/templates/ubuntu-application/internal/packaging.py 2012-03-05 19:54:52.000000000 +0000 @@ -75,7 +75,7 @@ for line in warn_output: if (re.match(".*not recognized by DistUtilsExtra.auto.*", line)): try: - if not re.match(' .*', warn_output[line_number + 1]): + if not re.match(' [^ ].*', warn_output[line_number + 1]): warn_output.remove(line) line_number -= 1 except IndexError: @@ -103,7 +103,7 @@ output_domain = DomainLevel.ERROR elif 'WARN' in line: output_domain = DomainLevel.WARNING - elif not line.startswith(' '): + elif not line.startswith(' ') or line.startswith(' dh_'): output_domain = DomainLevel.NONE if '[not found]' in line: output_domain = DomainLevel.WARNING @@ -199,7 +199,8 @@ contents = f.read() if contents and re.search('dpkg-distaddfile %s.svg' % project_name, contents) is None: contents += """ -common-install-indep:: +override_dh_install:: + dh_install cp %(icon_name)s ../%(project_name)s.svg dpkg-distaddfile %(project_name)s.svg raw-meta-data -""" % { 'project_name': project_name, 'icon_name': icon_name} diff -Nru quickly-11.12/data/templates/ubuntu-application/internal/quicklyutils.py quickly-12.03/data/templates/ubuntu-application/internal/quicklyutils.py --- quickly-11.12/data/templates/ubuntu-application/internal/quicklyutils.py 2011-11-01 16:48:06.000000000 +0000 +++ quickly-12.03/data/templates/ubuntu-application/internal/quicklyutils.py 2012-03-06 15:58:55.000000000 +0000 @@ -20,7 +20,7 @@ import sys import subprocess import tempfile -from xml.etree import ElementTree as etree +from lxml import etree import gettext from gettext import gettext as _ @@ -149,7 +149,8 @@ value -> new value attributes_if_new -> dictionnary of additional attributes if we create a new node""" found = False - xml_tree = etree.parse(xml_file) + parser = etree.XMLParser(remove_comments=False) + xml_tree = etree.parse(xml_file, parser=parser) if not attributes_if_new: attributes_if_new = {} attributes_if_new[attribute_name] = attribute_value diff -Nru quickly-11.12/data/templates/ubuntu-application/run.py quickly-12.03/data/templates/ubuntu-application/run.py --- quickly-11.12/data/templates/ubuntu-application/run.py 2011-12-15 19:48:28.000000000 +0000 +++ quickly-12.03/data/templates/ubuntu-application/run.py 2012-03-05 17:08:32.000000000 +0000 @@ -50,12 +50,12 @@ print _("Can't access to X server, so can't run gtk application") sys.exit(1) +env = os.environ.copy() # Compile schema if present schemapath = os.path.abspath("data/glib-2.0/schemas") if os.path.exists(schemapath): subprocess.call(["glib-compile-schemas", schemapath]) - env = os.environ.copy() datadir = os.path.abspath("data") if 'XDG_DATA_DIRS' in env: env['XDG_DATA_DIRS'] = "%s:%s" % (datadir, env['XDG_DATA_DIRS']) diff -Nru quickly-11.12/data/templates/ubuntu-application/test/metadata.sh quickly-12.03/data/templates/ubuntu-application/test/metadata.sh --- quickly-11.12/data/templates/ubuntu-application/test/metadata.sh 2011-12-15 19:48:28.000000000 +0000 +++ quickly-12.03/data/templates/ubuntu-application/test/metadata.sh 2012-03-14 23:46:56.000000000 +0000 @@ -15,20 +15,7 @@ # Ubuntu packaging created in debian/ # Ubuntu package has been successfully created in ../test-project_0.1_all.deb -cat debian/control | sed "s/project-$(lsb_release -c | cut -f2)*\./project-RELEASE./" -# Source: test-project -# Section: python -# Priority: extra -# Build-Depends: cdbs (>= 0.4.43), -# debhelper (>= 6), -# python, -# python-support (>= 0.6.4), -# python-distutils-extra (>= 2.10) -# Maintainer: UNKNOWN -# Standards-Version: 3.8.3 -# XS-Python-Version: current -# -# Package: test-project +grep -C1 "^XB-" debian/control | sed "s/project-$(lsb_release -c | cut -f2)*\./project-RELEASE./" # Architecture: all # XB-Python-Version: ${python:Versions} # XB-AppName: Test Project @@ -37,30 +24,25 @@ # XB-Thumbnail-Url: https://software-center.ubuntu.com/screenshots/t/test-project-RELEASE.thumb.png # XB-Icon: test-project.svg # Depends: ${misc:Depends}, -# ${python:Depends}, -# gir1.2-glib-2.0, -# gir1.2-launchpad-integration-3.0, -# yelp -# Description: UNKNOWN -# UNKNOWN cat debian/rules # #!/usr/bin/make -f -# DEB_PYTHON_SYSTEM := pysupport -# DEB_PYTHON_PREFIX_ARG := /opt/extras.ubuntu.com/test-project +# %: +# ifneq ($(shell dh -l | grep -xF translations),) +# dh $@ --with python2,translations +# else +# dh $@ --with python2 +# endif # -# include /usr/share/cdbs/1/rules/debhelper.mk -# include /usr/share/cdbs/1/class/python-distutils.mk -# # langpack.mk is relevant on Ubuntu only, not Debian; it does not matter if it's missing -# -include /usr/share/cdbs/1/rules/langpack.mk +# override_dh_auto_install: +# dh_auto_install -- --install-scripts=/opt/extras.ubuntu.com/test-project --install-data=/opt/extras.ubuntu.com/test-project --install-lib=/opt/extras.ubuntu.com/test-project # -# common-binary-post-install-arch:: -# -dh_icons -a +# override_dh_python2: +# dh_python2 /opt/extras.ubuntu.com/test-project # -# common-binary-post-install-indep:: -# -dh_icons -i # -# common-install-indep:: +# override_dh_install:: +# dh_install # cp data/media/test-project.svg ../test-project.svg # dpkg-distaddfile test-project.svg raw-meta-data - @@ -75,8 +57,9 @@ grep XB-Icon debian/control # XB-Icon: test-project.svg -tail -n 3 debian/rules -# common-install-indep:: +tail -n 4 debian/rules +# override_dh_install:: +# dh_install # cp data/media/logo.svg ../test-project.svg # dpkg-distaddfile test-project.svg raw-meta-data - diff -Nru quickly-11.12/data/templates/ubuntu-application/test/package.sh quickly-12.03/data/templates/ubuntu-application/test/package.sh --- quickly-11.12/data/templates/ubuntu-application/test/package.sh 2011-11-08 00:11:51.000000000 +0000 +++ quickly-12.03/data/templates/ubuntu-application/test/package.sh 2012-03-05 19:18:20.000000000 +0000 @@ -81,8 +81,8 @@ ar p ../../test-project_0.1_all.deb data.tar.gz | tar xz -grep -Rh "__version__ = " . +grep -Rh "__version__ = " usr/share/pyshared # __version__ = '0.1' -grep -Rh "__test_project_data_directory__ = " . +grep -Rh "__test_project_data_directory__ = " usr/share/pyshared # __test_project_data_directory__ = '/usr/share/test-project/' diff -Nru quickly-11.12/data/templates/ubuntu-pygame/help/po/de.po quickly-12.03/data/templates/ubuntu-pygame/help/po/de.po --- quickly-11.12/data/templates/ubuntu-pygame/help/po/de.po 1970-01-01 00:00:00.000000000 +0000 +++ quickly-12.03/data/templates/ubuntu-pygame/help/po/de.po 2012-03-14 23:57:45.000000000 +0000 @@ -0,0 +1,1118 @@ +# German translation for quickly +# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 +# This file is distributed under the same license as the quickly package. +# FIRST AUTHOR , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: quickly\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-04-04 08:43-0400\n" +"PO-Revision-Date: 2012-02-28 10:46+0000\n" +"Last-Translator: Launchpad Translations Administrators \n" +"Language-Team: German \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2012-02-29 04:43+0000\n" +"X-Generator: Launchpad (build 14874)\n" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:13(firstname) +msgid "Rick" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:14(surname) +msgid "Spencer" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:16(corpauthor) +msgid "Canonical ltd" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:20(date) data/templates/ubuntu-pygame/help/tutorial.xml:25(invpartnumber) +msgid "2010" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:0(application) +msgid "Quickly PyGame Template" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:24(productnumber) +msgid "0.6.1" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:26(title) +msgid "Quickly PyGame Template 0.6.1 Tutorial" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:31(title) +msgid "About This Guide" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:32(para) +msgid "" +"Use The Quickly Pygame Template to write old " +"school arcade games for running on Ubuntu. PyGame is a framework that " +"handles sprites, collisons, sounds, and everything you need to make a game. " +"You just need to add the game play. The Quickly template creates a starter " +"game for you and comes ready for you to turn into your fun game, and then " +"easily package and share it with other Ubuntu users." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:35(para) +msgid "" +"The Quickly Pygame Template inherits from the Quickly Application template. " +"So you get all the commands that you get from the that template, except " +"\"design\"." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:41(title) +msgid "Creating and Running Your Game" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:44(para) +msgid "" +"In this tutorial we will start making a top down shooter reminiscent of the " +"space arcade shooters of the 1980s." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:50(para) +msgid "" +"We'll do this by creating a default game, editing some of the generated " +"code, writing some new code, and adding our images for sprits." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:53(para) +msgid "" +"Creating a default working game couldn't be simpler. First, open a terminal " +"window to type commands into. When it's open, type the command:" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:56(programlisting) +#, no-wrap +msgid "" +"\n" +"$quickly create ubuntu-pygame shooter\n" +" " +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:60(para) +msgid "" +"This will create a shooter sub directory containing a complete directory " +"tree and files for an empty python application. The command finishes by " +"running the newly created game. The game is played by using the \"s\" and " +"\"f\" keys to rotate the guy, the \"j\" key to shoot, and the \"l\" key to " +"thrust." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:63(para) +msgid "" +"You can play the newly created game. Notice that the Quickly " +"PyGame Template inferred that the game title is \"Shooter\". " +"Also note that there is a guy that you can control with the s,f,j, and l " +"keys. There is an enemy and a homing missle. You also get a \"Game Over\" " +"screen, scoring, and levels build in for free." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:66(para) +msgid "" +"Close the game by closing the window or using the Esc key. Since the game " +"isn't installed into Ubuntu yet, you can't start the game from the " +"application menu yet. To start the game, use the terminal to first cd into " +"the new subdirectory, and then use \"quickly run\" to start the program." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:69(programlisting) +#, no-wrap +msgid "" +"\n" +"$cd shooter\n" +"$quickly run\n" +" " +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:75(title) +msgid "Creating your own Sprites" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:79(listitem) +msgid "" +"Ink Scape is a great and free tool for creating your sprites. It's in the " +"Featured Applications section of the Software Center." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:80(listitem) +msgid "" +"If you use Ink Scape, you'll want to export the images as PNGs. But keep the " +"Ink Scape files around in case you want to edit the sprites later." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:81(listitem) +msgid "" +"Whatever size you make the sprites, that's the size they will be in the game." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:82(listitem) +msgid "" +"The game will look for sprites in the data/media folder, so make sure you " +"put them there." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:76(para) +msgid "" +"The first think you probably noticed about the game is that the graphics are " +"so blah! Let's start by adding our own sprites. We;ll do a compbination of " +"replacing sprites with our own images, and also add a new sprite which we'll " +"use later. Here's a few things to keep in mind: " +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:85(para) +msgid "" +"I made new images for the guy (the sprite the player controls), enemies, " +"bullets, and the game background. I also made a new sprite called " +"\"enemy_bullet.png\" which we'll add into the game later. " +"Just drag your new sprite images into the shooter/data/media and tell it to " +"replace the images. Now when you run the game, you'll see your new sprites " +"at work. Oops. As you can see, the background image I " +"created was for a game of different dimensions. It's for a game that's 400 " +"pixels wide by 500 pixels high. In the next section, we'll make the game " +"that size." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:98(title) +msgid "Changing the Screen Dimensions" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:99(para) +msgid "" +"The first change we'll make is to change the screen dimensions to be " +"oriented from top to bottom. We do this by changing a little code. So let's " +"fire up the code editor first. Run the edit command to fire up the editor." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:102(programlisting) +#, no-wrap +msgid "$quickly edit" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:104(programlisting) +#, no-wrap +msgid "" +"\n" +"#screen dimensions\n" +"screen_width = 400\n" +"screen_height = 500\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:103(para) +msgid "" +"This command should open your code in Gedit. The screen dimensions are set " +"in the file \"shooterconfig.py\". So just go to that file and change the " +"width to 400 and the height to 500. Save the file and run " +"the game again. Notice that the screen wrapping and centering and everything " +"was taken care of for you. That's because you made the change in the " +"shooterconfig.py file. This is the right place to add and change variables " +"that should be availble throughout the game. We'll be make a few more " +"changes here later." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:114(title) +msgid "Programming the Guy" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:115(para) +msgid "" +"For this game, what we want is the guy to move left and right across the " +"bottom and not wrap through the screen. Also, we want to make the bullets " +"look like they are coming out of the guy's front." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:121(listitem) +msgid "" +"Place the guy at the beginning of each level at the middle and bottom of the " +"screen." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:122(listitem) +msgid "" +"Add functions to guy.py for moving and stop movig right and left, and remove " +"the rotate functions." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:123(listitem) +msgid "" +"Change the keyboard input in the bin/shooter file to call these new " +"functions." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:118(para) +msgid "To make the guy move just left and right we need to: " +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:128(programlisting) +#, no-wrap +msgid "" +"\n" +" def init_position(self):\n" +" \"\"\"init_position - resets the Guy's position near the\n" +" bottom of the screen\n" +" \n" +" \"\"\"\n" +" sw = shooterconfig.screen_width\n" +" sh = shooterconfig.screen_height\n" +"\n" +" self.x = sw/2\n" +" self.y = sh - 80\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:143(listitem) +msgid "start_moving_left: the user pressed the \"s\" key" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:144(listitem) +msgid "stop_moving_left: the user released the \"s\" key" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:145(listitem) +msgid "start_moving_right: the user pressed the \"f\" key" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:146(listitem) +msgid "stop_moving_right: the user released the \"f\" key" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:150(listitem) +msgid "Create two tracking variables, _moving_left and _moving_right" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:151(listitem) +msgid "" +"Set these tracking variables to True or False in the " +"start/stop_moving_left/right functions" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:152(listitem) +msgid "" +"In the guy's update function, change the x coordinates of the guy based on " +"these variables" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:126(para) +msgid "" +"The functionaly that is specific to the player's sprite is in the guy.py " +"file. The first thing we will do is work on placing the guy properly. " +"Fortunately, the is an existing function that we can modify for this. The " +"function init_position is called to each time the guy needs to be placed on " +"the screen, like after he gets killed for instance . When created, the guy " +"calls the based class function center_on_screen. As you may guess, we will " +"want to change this function. so the guys is positionedhalfway down the " +"screen, and we want him to start a few pixels from the bottom. Fortunaately " +"we know how to get the screen dimensions, so it's easy make the change to " +"init_position. Now when you run the game, the guy starts at " +"the bottom, which is what we want, but he also rotates when we use the s and " +"the d button, which we do not want. So let's change that next by " +"implementing four new functions: Here's how we will " +"implement these functions: " +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:158(programlisting) +#, no-wrap +msgid "" +"\n" +" self._moving_left = False\n" +" self._moving_right = False\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:164(programlisting) +#, no-wrap +msgid "" +"\n" +" def start_moving_right(self):\n" +" self._moving_left = False\n" +" self._moving_right = True\n" +"\n" +" def start_moving_left(self):\n" +" self._moving_left = True\n" +" self._moving_right = False\n" +"\n" +" def stop_moving_left(self):\n" +" self._moving_left = False\n" +"\n" +" def stop_moving_right(self):\n" +" self._moving_right = False\n" +"\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:156(para) +msgid "" +"First, add the tracking variables to the Guy.__init__function. Add these " +"after the call to BaseSprite.__init__(). Now the functions " +"for responding to keys simply set those tracking variables as appropriate. " +"So we add these four new functions to guy.py. " +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:181(para) +msgid "" +"Now we need change the guy's coordinates based on the tracking variable. " +"Every sprite has an update function. This function is called for every " +"\"tick\" in the game, and the sprite looks at it's internal data, and " +"updates itself appropriately. By default, the guy's rotation is handled by " +"BaseSprite, so we can ignore that, especially since we won't be using " +"rotation anyway. We're also not using acceleration for the guy, so we can " +"delete a bit of code. Funally, we don't want the guy to \"wrap\" though the " +"screen, so we whould catch that condition." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:186(programlisting) +#, no-wrap +msgid "" +"\n" +" def update(self):\n" +" \"\"\"update - Update internal data for a game tick\"\"\" \n" +" \n" +" BaseSprite.update(self)\n" +"\n" +" if self._moving_left:\n" +" self.x -= 5\n" +" if self.x < 0:\n" +" self.x = 0\n" +" if self._moving_right:\n" +" self.x += 5\n" +" if self.x + self.rect.width > shooterconfig.screen_width:\n" +" self.x = shooterconfig.screen_width - self.rect.width\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:184(para) +msgid "" +"Let's start with moving the guy 5 pixels per tick. So we can change the top " +"of the update function to look like this: " +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:202(para) +msgid "" +"So the guy is ready. He starts in the right place, tracks whether he is " +"moving left or right, and updates his position as desired. Now we just need " +"to hook him up the keys." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:205(para) +msgid "" +"Keyboard contol is handled in the shoort file in the bin directory. For each " +"click of the clock, the controller_tick function is called. Detecting " +"keyboard input and directing it as appropriate is handled in this funciton. " +"So what we wante to do is find where the f and s key events are handled, and " +"call the guy's start/stop_moving_left/right functions there." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:211(listitem) +msgid "Call the start_moving functions instead of rotate functions." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:212(listitem) +msgid "Remove the call to the accelerate function." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:213(listitem) +msgid "Remve the call to the hyperspace function." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:216(programlisting) +#, no-wrap +msgid "" +"\n" +" #control the guy\n" +" if not game.paused: \n" +" if event.key == pygame.K_f:\n" +" g.start_moving_right()\n" +" if event.key == pygame.K_s:\n" +" g.start_moving_left()\n" +" if event.key == pygame.K_j:\n" +" g.shoot()\n" +"\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:208(para) +msgid "" +"Key down events are handled first, in a section commented \"control\" the " +"guy. We want to make a few changes here. These last two " +"functions aren't needed for our new game. So let's make the changes and this " +"part of the controller_tick function will change to this: " +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:230(programlisting) +#, no-wrap +msgid "" +"\n" +" #key up events, typically stop actions\n" +" if event.type == pygame.KEYUP:\n" +" if event.key == pygame.K_F11:\n" +" pygame.display.toggle_fullscreen() \n" +" if event.key == pygame.K_f:\n" +" g.stop_moving_right()\n" +" if event.key == pygame.K_s:\n" +" g.stop_moving_left()\n" +"\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:228(para) +msgid "" +"We'll handle the key up functions similarly. " +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:248(listitem) +msgid "" +"The bullets accelerate and go way to fast, they'll miss enemies by skipping " +"over them." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:249(listitem) +msgid "" +"The bullets should go to the top of the screen, and not stop before or wrap " +"around" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:250(listitem) +msgid "" +"The bullets should appear to come out of the middle of the guy, instead of " +"the side." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:253(programlisting) +#, no-wrap +msgid "" +"\n" +" self.max_velocity = 20\n" +" self.max_ticks = 20\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:258(programlisting) +#, no-wrap +msgid "" +"\n" +" def update(self):\n" +" \"\"\"update - update internal data and position.\n" +" Typically called by the game controller each game\n" +" tick.\n" +"\n" +" \"\"\"\n" +"\n" +" BaseSprite.update(self)\n" +"\n" +" if self.y < 1:\n" +" self.kill()\n" +" if self.y == shooterconfig.screen_height:\n" +" self.kill()\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:282(programlisting) +#, no-wrap +msgid "" +"\n" +" def shoot(self):\n" +" \"\"\"shoot - fire a bullet. Adds the bullet to the bullet sprite " +"group.\n" +" If the maximum number of bullets premitted would be exceeded, \n" +" the bullet will not fire. If the guy is exploding, the guy will no\n" +" fire.\n" +"\n" +" \"\"\"\n" +"\n" +" if self.alive:\n" +" #only allow max numbe of bullets on the screen at a time\n" +" if len(self.bullets.sprites()) < self.max_bullets:\n" +" center_x = (self.x + self.rect.width / 2) - 3\n" +" b = Bullet(center_x,self.y,self.orientation)\n" +" self.bullets.add(b)\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:245(para) +msgid "" +"Now we've got the guy working the way we want, but we need to make a few " +"changes to to how the guy's bullets are working: We'll " +"handle the first problem my changing the Bullet class in the bullet.py file. " +"The acceleration and speed of bullets in the game is configured in the " +"__init__ function of this file. The rate at whcih a bullet accelerates is " +"controlled by member variable acceleration_divisor. We won't need to change " +"that. However, the maximum speed a bullet will reach is defined ny " +"max_velocity, and the lifetme of the bullet is defined by max_ticks. Let's " +"make the bullets go slower, but last longer, by changing max_velocity to 20, " +"and max_ticks to 20 in the Bullet __init__ funciton. This " +"simple change is all that is necessary to control the bullets throughout the " +"game. Note that making this change in the Bullet class means all bullets in " +"the game, including enemy bullets, will now work this way. So let's quickly " +"deal with stopping bullets from wrapping as well. We'll add to the Bullet " +"class's update function to see if the bullet is above or below the screen, " +"and if so, we'll remove it. So we'll change the to of the update function in " +"bullet.py to look like this: Note that a Sprite's kill " +"function, removes it from the game immediately, and with no fanfare. " +"Finally, we need to adjust the bullet so it comes out from the guys the way " +"we want it to. Since this is only related to the way the guy shoots bullets " +"and won't have anything to do with enemy bullets, we'll configure how " +"bullets emerge in the guy.py file. Let's just tweak the shoot function a " +"bit. As you can see in this function, when you create a bullet, you provide " +"it x and y coordinates. We'll just calculate at better x coordinate to " +"start. We'll find the middle of the width of the guy's image, and offset it " +"a bit so the bullet sprite looks like it comes out correctly. " +" center_x = (self.x + self.rect.width / 2) - 3 " +" So we change change the ugy's shoot funciton to look like " +"this: " +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:299(para) +msgid "" +" Now we have the guy working as desired. Moves back and " +"forth across the bottom and shoots bullets the way we want. Next we'll go on " +"to changing the way the enemies work." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:308(title) +msgid "Programming Enemies" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:309(para) +msgid "" +"The generated game always adds two enemies for each level, a homing missle " +"and a stock \"enemy\". The homing missle does pretty much what's it name " +"suggests, homes in on the guy and kills him. The Enemy doesn't do much of " +"anything. Just kind of plunks down and waits to get killed. First we're " +"going to remove the homing missle from the game, and then we'll customize " +"the enemies to be a bit more menancing." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:314(programlisting) +#, no-wrap +msgid "" +"\n" +" #TODO: set up enemies here\n" +" #You can add more enemies or use different enemies\n" +" #depening on the level\n" +" for i in xrange(0,game.level + 3):\n" +" enemies.add(Enemy())\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:312(para) +msgid "" +"The bin/shooter fileset up a SpriteGroup already. It's called \"enemies\" " +"and gets populated each time a new level is created. New levels are created " +"in the next_level function in the bin/shooter file. The next_level function " +"is pretty simple, it increments the game level bu 1, removes any remaining " +"emenemities for the SpriteGroup and then repulates the enemies SpriteGroup. " +"Let's make a couple of basic chagnnges here. First, we'll change the xrange " +"so that it creates more enemies with each level, and second, we'll just " +"delete the line that creates the homing missle. Change the next_level " +"function to make the last few lines as below. So for the " +"first level, there will by for enemies, and each time there is an new level " +"created the number of enemies will increase by 1. Aslo, no more homing " +"missles. " +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:326(para) +msgid "" +"However, there are two things we need to do to enhance the game play with " +"our enemies. First, as you can see, they can start quite close to the guy, " +"even under. We'll need to fix that. Also, we should put them in motion so " +"they are a bit more of a challenge to shoot. We'll do both of the things by " +"modifying the Enemy class in the enemy.py file. Specifically in the " +"init_postion function." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:329(para) +msgid "" +"If you open the enemy.py file and look for the init_position function, " +"you'll see there is a call to the function in __init__ but there is no " +"function for it. That's because enemy inherits from BaseSprite, which has a " +"default init_position implementation that randomly places it on the screen. " +"So we'll simply override the init_position function in the Enemy class in " +"enemy.py." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:334(programlisting) +#, no-wrap +msgid "" +"\n" +" sh = shooterconfig.screen_height\n" +" sw = shooterconfig.screen_width\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:339(programlisting) +#, no-wrap +msgid "" +"\n" +"import random\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:343(programlisting) +#, no-wrap +msgid "" +"\n" +" self.x = random.randint(20,sw - self.rect.width - 20)\n" +" self.y = random.randint(20,sh/2)\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:348(programlisting) +#, no-wrap +msgid "" +"\n" +" self.velocity_x = random.randint(-30,30)\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:352(programlisting) +#, no-wrap +msgid "" +"\n" +" def init_position(self):\n" +" sh = shooterconfig.screen_height\n" +" sw = shooterconfig.screen_width\n" +"\n" +" self.x = random.randint(20,sw - self.rect.width - 20)\n" +" self.y = random.randint(20,sh/2)\n" +" self.velocity_x = random.randint(-30,30)\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:332(para) +msgid "" +"First, to make it a bitter easier to code, grab a reference to the screen " +"height and widgth that you configured and keep those in easier to use " +"variables. Next, we want to choose random start position " +"along the X axis. But we don't want the enemy to start too close to either " +"side or it might get stuck in a spot where the guy can't shoot it. To " +"generate random integers, use the randome module, so you'll have to add an " +"import to the top of the file. We can use the screenwidth " +"to and the enemies own width to determine the right most starting position. " +"For the Y axis, we want the enemies to be far enough away that they can't " +"too easily kill the guy. We'll also make sure they don't get out of reach of " +"the guy's bullets. So between 20 and half way down seems about right. " +" Finally, let's put each enemy in motion by picking a random " +"velocity_x within some reasonable bounds. Notice that one " +"in 60 of the enemies won't be moving. That's okay because we added padding " +"to keep the enemies from ending up too close to the sides. The full " +"init_position function you need to add looks like this: " +"When you run the game, you can see that the enemies are moving and are good " +"targets to shoot at. But next we'll make the enemies fight back." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:366(listitem) +msgid "Figure out where to place the bullet on the screen" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:367(listitem) +msgid "Configure the bullet's velocity and maximum speed" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:368(listitem) +msgid "Create the bullet object and add it to a SpriteGroup" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:371(programlisting) +#, no-wrap +msgid "" +"\n" +"#create the player's guy and some enemies\n" +"bullets = pygame.sprite.RenderUpdates()\n" +"g = Guy(bullets)\n" +"enemies = pygame.sprite.RenderUpdates()\n" +"enemy_bullets = pygame.sprite.RenderUpdates()\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:380(listitem) +msgid "" +"Clear out all the sprites in the group when creating a new level or " +"resetting a level after the guy dies." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:381(listitem) +msgid "" +"Tell the bullets in the sprite group to update themselves at the right time." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:382(listitem) +msgid "Tell the bullets to draw themselves at the right time." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:383(listitem) +msgid "" +"Pass a reference to the sprite group to each enemy that is created, so it " +"can add it's bullets to the group." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:386(programlisting) +#, no-wrap +msgid "" +"\n" +" enemies.empty()\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:390(programlisting) +#, no-wrap +msgid "" +"\n" +"def update_sprites():\n" +" \"\"\"update_sprites - call update() for all sprites\"\"\"\n" +" g.update()\n" +" bullets.update()\n" +" enemies.update() \n" +" enemy_bullets.update()\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:399(programlisting) +#, no-wrap +msgid "" +"\n" +" #draw enemies\n" +" enemies.draw(screen)\n" +" enemy_bullets.draw(screen)\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:405(programlisting) +#, no-wrap +msgid "" +"\n" +" def __init__(self,enemy_bullets):\n" +" \"\"\"Creates an Enemy \"\"\"\n" +" self.enemy_bullets = enemy_bullets\n" +"\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:412(programlisting) +#, no-wrap +msgid "" +"\n" +" enemies.add(Enemy(enemy_bullets))\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:416(programlisting) +#, no-wrap +msgid "" +"\n" +"from bullet import Bullet\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:421(programlisting) +#, no-wrap +msgid "" +"\n" +" def shoot(self):\n" +" if self.alive:\n" +" b = Bullet(self.x,self.y, 180)\n" +" b.max_velocity = 6\n" +" b.max_ticks = 50\n" +" self.enemy_bullets.add(b)\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:431(programlisting) +#, no-wrap +msgid "" +"\n" +" if not game.paused:\n" +" for e in enemies:\n" +" if random.randint(0,20) == 1:\n" +" e.shoot()\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:441(programlisting) +#, no-wrap +msgid "" +"\n" +"enemy_bullet_image = image_path + \"enemy_bullet.png\"\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:445(programlisting) +#, no-wrap +msgid "" +"\n" +" def shoot(self):\n" +" if self.alive:\n" +" img = shooterconfig.enemy_bullet_image\n" +" b = Bullet(self.x,self.y, 180, img)\n" +" b.max_velocity = 6\n" +" b.max_ticks = 50\n" +" self.enemy_bullets.add(b)\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:363(para) +msgid "" +"Let's add the ability for an enemy to drop a bomb. By default, enemies can't " +"do anything like that, so we'll have to add a new function. The function " +"will need to do the following things: We should probably " +"start with this last part. We'll want to create a special sprite group for " +"the bullets to go into. This is primarily so that we can use the " +"SpriteGroups collision detection capabilities later. Also it's easier to " +"manage updates of sprites when they are in a group. First things first, " +"we'll create the sprite group. There's a place in the bin/shooter for " +"setting up enemies and such, so create another sprite group there. You " +"create a sprite group by calling a function in the pygame.sprite module " +"called \"RenderUpdates\". Lookk for the code block below, and notice the new " +"line creating the new sprite group by calling RenderUpdates. Now that we have the sprite group called enemy_bullets we want to do " +"three more things with it for now. So for the first part, " +"we'll call the sprite group's empty function in next_level and reset_level " +"This function simply removes each sprite in the sprite group from game play. " +"Do this as the first thing for each of these function. For " +"the second point, we'll add to the function in bin/shooter called " +"update_sprites. As you may have guessed, this function is called each tick " +"and tells each sprite to update. For sprites in a sprite group, this is " +"easy, because the SpriteGroup class includes an update function that calls " +"update for each of it's sprites. So just add that to the end of the " +"update_sprites function in bin/shooter, so it looks like the listing here: " +" The view_tick function is called once per tick as well. " +"This funciton updates the view on the screen. We'll add a line of code to " +"tell the bullets to draw themselves right under where the enemies draw " +"themselves. Finally, we need to pass a reference to each " +"enemy as it is created and create a member variable to store that reference. " +"So we need to make a change in the enemy.py fil, to add an argument for the " +"SpriteGroup in the __init__ function, and also we need to pass the " +"SpriteGroup when creating enemies. So change the Enemy class in enemy.py so " +"the top of the __init__ function looks like so: And then " +"back in the bin/shooter file in the next_level function when creating " +"enemies, pass in enemy_bullets. Now we have a functioning " +"sprite group and the enemies have a reference to it, we are ready to start " +"actually adding some bullets to it. We'll do this by adding a member " +"function called \"shoot\" to the enemy. Don't forget to import the Bullet " +"class into the enemy.py file. First thing is we'll check " +"that the enemy is alive. We don't have to do this, but for this game, we " +"don't want it to shoot if it's int the process of exploding. Then we'll just " +"create a bullet and add it to the SpriteGroup. The last argument we'll pass " +"in is to set the orientatin to 180. Orientation goes clockwise for 360 " +"degrees, with zero being directly up, and 180 being directly down. In code, " +"it looks like the listing below. So now we just need to " +"tell the enemies to shoot. We'll do this back in the bin/shooter file, in " +"the\"controller_tick function. After the section where we respond to " +"keyboard input, we'll add a few lines to make the enemies shoot. First, " +"we'll make sure the game is not paused, not very fair to shoot in a paused " +"game, is it? Next we'll loop through the enemies and desider if we should " +"call shoot. using our friend random.randint, we'll do this say, one time " +"twenty. So if you add this code to the end of the controller_tick function, " +"your enemies will start dropping bombs. " +"So if you run the game, you'll see that the enemies are dropping bulltes " +"like bombs. Nice. However, maybe it would be nicer if the sprites for the " +"enemy bullets were different than the sprites for the guy's bullets. " +"Remember at the beginning of the tutorial we added an image called " +"enemy_bullet.png to the data/media directory. Now we'll write a bit of code " +"to use that image. First thing, we should add a reference to it in the " +"shooterconfig.py file. In this way, the Enemy class will be able to find it. " +"Just add the following line along with the other image path setting code in " +"shooterconfig.py. So now we need to tell the bullets in " +"the Enemy class to use that image. Fortunately the Bullet class takes an " +"optional parameter for the name of an image to use. So just modify the shoot " +"function in the Enemy class to include the path. Now the " +"enemies are dropping bombs with our new image. " +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:459(para) +msgid "" +"But of course, you many notice the bombs aren't too menancing. In the next " +"chapter we'll add collision detection to make the bombs kill the guy." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:464(title) +msgid "Collision Detection" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:465(para) +msgid "" +"Collision detection is when you check for sprites that are overlapping, and " +"run code based on what happened. PyGame makes this very easy by providing " +"some functions to check for overlapping sprites for you. As you will see, it " +"works for individual sprites as well as sprite groups." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:470(programlisting) +#, no-wrap +msgid "" +"\n" +" b = pygame.sprite.spritecollideany(g, enemy_bullets)\n" +" if b != None:\n" +" g.explode()\n" +" b.kill()\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:481(programlisting) +#, no-wrap +msgid "" +"\n" +" hits_dict = pygame.sprite.groupcollide(bullets, enemy_bullets, True, " +"False)\n" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:468(para) +msgid "" +"Ok, so let's start by making the bombs that the enemies drop actually kill " +"the guy. To do this, we want to check if the bombs ever collide with the " +"guy, and if they do, we'll tell the guy to explode, and then we'll remove " +"the bomb from the screen. So the logic is \"tell me if the guy collides with " +"any enemy_bullets\". There is a funciton for this called, " +"pygame.sprite.spritecollideany, which takes a single sprite and a sprite " +"group and returns a reference to any sprite in the sprite group that " +"collided with the single sprite. If there were no collisions, than e will be " +"None. Otherwise, we'll want to tell the guy to explode and tell the bullet " +"to just \"kill\", which will remove it from play. So we can call it like " +"this: There is a function in bin/shooter called " +"check_collisions which is called once per tick, and is the perfect place to " +"add this code. Add it right under the similar test for the guy colliding " +"with enemies. Now those bombs can kill the guys. If you " +"play for a bit, you may notice that the bullets and the bombs just kind of " +"pass by each other. We can ramp up the game play by making the enemy bullets " +"destroy the guy's bullets, but not visa versa. So that logic here is, have " +"any of the sprites in the bullets sprite group collided with the bullets in " +"the enemy bullets sprite group. There is function for this as well, " +"pygame.sprite.groupcollide. groupcollide takes two sprite lists and returns " +"a dictionary. The keys in the dictionary are any sprites from the first " +"group that are involved in a collision, and the values are the sprites from " +"the second group that collided with the sprite that for key. It's a bit hard " +"to explain, but I bet the code is pretty readable. Add this line to the " +"check_collisions function. Now if you run the game, it's a " +"bit more challenging as the enemies are a bit more offensive. This code just " +"kills the bullets involed in any collisions. Notice that I passed in True " +"False at the end of this function. These paramaters determine whether to " +"kill sprites form either group involved in the collusion. The True tells the " +"function to kill any bullets involved in collisions, so this was simple to " +"code." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:488(title) +msgid "Playing Sounds" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:491(programlisting) +#, no-wrap +msgid "" +"\n" +"tink_sound = sound_path + \"tink.wav\" \n" +" " +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:495(programlisting) +#, no-wrap +msgid "" +"\n" +"#set up some objects and models\n" +"tink_sound = pygame.mixer.Sound(shooter.shooterconfig.tink_sound) \n" +" " +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:500(programlisting) +#, no-wrap +msgid "" +"\n" +" hits_dict = pygame.sprite.groupcollide(bullets, enemy_bullets, True, " +"False)\n" +" if len(hits_dict) > 0:\n" +" tink_sound.play() \n" +" " +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:506(programlisting) +#, no-wrap +msgid "" +"\n" +" self.launch_sound = " +"pygame.mixer.Sound(shooterconfig.guy_shoot_sound)\n" +" self.launch_sound.set_volume(.2)\n" +" self.launch_sound.play() \n" +" " +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:489(para) +msgid "" +"The game is pretty much done in terms of game play, but I want to make one " +"small enhancement. When the enemy bullets kill one of the guy's bullets, I'd " +"like to play a little sound to signify this. So first, I added a little " +"\"tink\" sound to the data/media directory. After you add your sound, you " +"need to add a reference to it in the shootercongif.py file. " +"Now, I want to add a little code after the collision detection between the " +"bullets to play that sound if they collided. I can't just hop straight to " +"that though, first I have to create a sound object.In pygame you manage " +"sounds with the \"mixer\" module. I don't want to create this object over " +"and over again. So I'll add it to the bin/shooter file where the other " +"objects and such for the game are set up. Now that I've " +"told the mixer module to give me a sound, I can go ahead and check if there " +"were any collisions between bullets, and play my sound. So " +"it seems to be working well, but what if you are finding that one of the " +"sounds is too quiet or too loud? Or perhpas you want a certain sound to be " +"loud sometimes and queit other times, for example to simulate distance. This " +"is easy to do because each sound object has a set_volume function that you " +"can use to set the sound between 0 (for slient) and 1 (for normal volume). " +"The bullet launch sound I used was a bit loud, so in the bullet.py file, " +"I'll adjust the Bullet class to play the sound a bit more quietly. " +"" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:514(title) +msgid "Conclusion" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:518(listitem) +msgid "Creating a game using $quickly create ubuntu-pygame" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:519(listitem) +msgid "Adding your own sprites to the game" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:520(listitem) +msgid "Setting the screen size and other info in the config file" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:521(listitem) +msgid "Programming a player's guy to respond to keyboard input and to shoot" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:522(listitem) +msgid "Programming enemies to move and shoot" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:523(listitem) +msgid "Using collision detection to blow up Sprites" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:524(listitem) +msgid "Playing and adjusting sounds" +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:528(listitem) +msgid "" +"The bullets that the guy shoots and the bombs that the enemies drop make the " +"same sound, it would probably be nicer if they each made a different sounds." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:529(listitem) +msgid "" +"The default explosions are crayon drawings, they don't fit in much with the " +"look of the game. Perhaps some new images for the explosion stages would be " +"good." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:530(listitem) +msgid "" +"There are no power ups! You could create power up classes the derive from " +"BaseSprite to give the guy extra powers, like bigger bullets, more bullets, " +"or extra lives." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:531(listitem) +msgid "" +"More special enemies, for example you could use the HomingMissle class to " +"create harder to kill enemies." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:532(listitem) +msgid "" +"The high score list is stored in desktopcouch, so it will sync with your " +"other computers. But it will have to be adjusted to the size we set for the " +"window, and perhaps you can also let the player choose the name that's " +"stored." +msgstr "" + +#: data/templates/ubuntu-pygame/help/tutorial.xml:515(para) +msgid "" +"So now you have a working game! This tutorial introduced the following key " +"concepts for using the Quickly PyGame Template. But there " +"is still a lot to do to have a propper game. For example: " +msgstr "" + +#. Put one translator per line, in the form of NAME , YEAR1, YEAR2 +#: data/templates/ubuntu-pygame/help/tutorial.xml:0(None) +msgid "translator-credits" +msgstr "" +"Launchpad Contributions:\n" +" Daniel Dietrich https://launchpad.net/~shaddowy2" diff -Nru quickly-11.12/debian/changelog quickly-12.03/debian/changelog --- quickly-11.12/debian/changelog 2012-03-06 15:24:11.000000000 +0000 +++ quickly-12.03/debian/changelog 2012-03-15 00:31:01.000000000 +0000 @@ -1,3 +1,15 @@ +quickly (12.03-0ubuntu1) precise; urgency=low + + * New upstream release + - Tutorial update (LP: #929417, LP: #929420, LP: #929572) + - Fix crash when creating derived-template projects (LP: #936379) + - Don't strip comments from glade files (LP: #945808) + * debian/rules: + - Move project_root schema file to template directory after + python-distutils-extra zealously places it in system schema folder. + + -- Michael Terry Wed, 14 Mar 2012 20:30:12 -0400 + quickly (11.12-0ubuntu2) precise; urgency=low * debian/control: diff -Nru quickly-11.12/debian/rules quickly-12.03/debian/rules --- quickly-11.12/debian/rules 2011-09-30 21:11:47.000000000 +0000 +++ quickly-12.03/debian/rules 2012-03-15 00:24:58.000000000 +0000 @@ -2,3 +2,11 @@ %: dh $@ --with python2 + +override_dh_auto_install: + dh_auto_install + + # python-distutils-extra likes to move any schema it finds to system location + mkdir -p debian/tmp/usr/share/quickly/templates/ubuntu-application/project_root/data/glib-2.0/schemas/ + mv debian/tmp/usr/share/glib-2.0/schemas/net.launchpad.project_name.gschema.xml debian/tmp/usr/share/quickly/templates/ubuntu-application/project_root/data/glib-2.0/schemas/ + rmdir --ignore-fail-on-non-empty debian/tmp/usr/share/glib-2.0/schemas/ diff -Nru quickly-11.12/MANIFEST quickly-12.03/MANIFEST --- quickly-11.12/MANIFEST 2011-12-22 16:52:35.000000000 +0000 +++ quickly-12.03/MANIFEST 2012-03-15 00:02:10.000000000 +0000 @@ -189,6 +189,7 @@ data/templates/ubuntu-pygame/help/images/7.png data/templates/ubuntu-pygame/help/images/8.png data/templates/ubuntu-pygame/help/images/9.png +data/templates/ubuntu-pygame/help/po/de.po data/templates/ubuntu-pygame/help/po/en_GB.po data/templates/ubuntu-pygame/help/po/es.po data/templates/ubuntu-pygame/help/po/fi.po diff -Nru quickly-11.12/NEWS quickly-12.03/NEWS --- quickly-11.12/NEWS 2011-12-15 19:59:12.000000000 +0000 +++ quickly-12.03/NEWS 2012-03-14 23:51:56.000000000 +0000 @@ -1,3 +1,13 @@ +Quickly 12.03 +------------------------------------ + + + ubuntu-application: + - Don't strip comments from glade files (Frederik Elwert) + - Update tutorial to match current code + + common: + - Fix inheriting 'create' in derived templates + - Fix crash during 'create' for derived templates (Paolo Sammicheli) + Quickly 11.12 ------------------------------------ diff -Nru quickly-11.12/PKG-INFO quickly-12.03/PKG-INFO --- quickly-11.12/PKG-INFO 2011-12-22 16:52:35.000000000 +0000 +++ quickly-12.03/PKG-INFO 2012-03-15 00:02:10.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: quickly -Version: 11.12 +Version: 12.03 Summary: build new Ubuntu apps quickly Home-page: https://launchpad.net/quickly Author: Quickly Developer Team diff -Nru quickly-11.12/po/fi.po quickly-12.03/po/fi.po --- quickly-11.12/po/fi.po 2011-12-15 20:04:09.000000000 +0000 +++ quickly-12.03/po/fi.po 2012-03-14 23:57:04.000000000 +0000 @@ -8,14 +8,14 @@ "Project-Id-Version: quickly\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-07-29 10:06+0200\n" -"PO-Revision-Date: 2011-12-12 16:33+0000\n" +"PO-Revision-Date: 2011-12-25 05:51+0000\n" "Last-Translator: Tuomas Lähteenmäki \n" "Language-Team: Finnish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-12-13 05:03+0000\n" -"X-Generator: Launchpad (build 14458)\n" +"X-Launchpad-Export-Date: 2011-12-26 04:54+0000\n" +"X-Generator: Launchpad (build 14560)\n" #: ../data/templates/ubuntu-application/edit.py:39 msgid "" @@ -30,7 +30,7 @@ #: ../data/templates/ubuntu-application/create.py:35 msgid "quickly create