[pygtk-docs] * Merge all changes together



commit 3830b028c71d87d8dbcceff5ab68c29edd983234
Author: John Finlay <finlay moeraki com>
Date:   Wed Jul 8 15:16:49 2009 -0700

    	* Merge all changes together

 2.0/ChangeLog                               |  553 -----
 2.0/Makefile                                |  213 --
 2.0/html.xsl                                |  269 ---
 2.0/tut-es/ChangeLog                        |  391 ---
 2.0/tut-es/ComboBoxAndComboBoxEntry.xml     |  432 ----
 2.0/tut-es/TreeViewWidget.xml               | 1761 --------------
 2.0/tut/CellRenderers.xml                   | 1114 ---------
 2.0/tut/ChangeLog                           |  388 ---
 2.0/tut/ComboBoxAndComboBoxEntry.xml        |  445 ----
 2.0/tut/Credits.xml                         |  147 --
 2.0/tut/GettingStarted.xml                  |  705 ------
 2.0/tut/Introduction.xml                    |  219 --
 2.0/tut/MiscellaneousWidgets.xml            | 3440 ---------------------------
 2.0/tut/PackingWidgets.xml                  |  818 -------
 2.0/tut/TipsForWritingPygtkApplications.xml |  452 ----
 2.0/tut/UndocumentedWidgets.xml             |   80 -
 ChangeLog                                   |   42 +
 Makefile                                    |   50 +-
 2.0/README => README                        |    0
 {2.0/examples => examples}/message.py       |    0
 html.xsl                                    |   35 +-
 2.0/pdf-dblatex.xsl => pdf-dblatex.xsl      |    0
 2.0/style.css => style.css                  |    0
 tut-es/ComboBoxAndComboBoxEntry.xml         |   12 +-
 tut-es/TreeViewWidget.xml                   |    2 +-
 tut/CellRenderers.xml                       |    7 +-
 tut/ChangeLog                               |   20 +
 tut/ComboBoxAndComboBoxEntry.xml            |   13 +-
 tut/Credits.xml                             |   61 +-
 tut/GettingStarted.xml                      |   20 +-
 tut/Introduction.xml                        |    6 +-
 tut/MiscellaneousWidgets.xml                |   62 +
 tut/PackingWidgets.xml                      |   92 +-
 tut/TipsForWritingPygtkApplications.xml     |  440 ++++-
 tut/UndocumentedWidgets.xml                 |    7 -
 {2.0/tut => tut}/singlewidget.pic           |    0
 {2.0/tut => tut}/twowidget.pic              |    0
 37 files changed, 757 insertions(+), 11539 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index d001e5e..9805fe1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,48 @@
 
 	* pygtk-docs.doap: Add file.
 
+2009-02-24  John Finlay  <finlay moeraki com>
+
+	* style.css: Add css file to avoid use of deprecated shade.verbatim.
+
+	* html.xsl: Remove usage of shade.verbatim - use style.css instead.
+
+	* Makefile (CSSFILES): Add style.css handling to avoid deprecated
+	shade.verbatim usage.
+
+	* README: Add dependency on GraphicsMagick.
+
+2008-10-21  Eric S. Raymond  <esr snark thyrsus com>
+
+	* tut/PackingWidgets.xml:Coopted the explanation of the box model
+	from the PyGTK FAQ for the Theory of Packing Boxes section.
+
+	* singlewidget.pic, twowidget.pic: Illustrations for the new box
+	model explanation.
+
+	* tut/Credits.xml: New subsection started to acknowledge that some
+	material has been lifted from the FAQ.
+
+	* README: Add tips for people interested in improving the tutorial.
+
+	* tut/GettingStarted.xml: Improved explanation of connect_object,
+	and a nod to the existence of hide() method because it helps
+	underline the fumction of show().
+
+	* turt/TipsForWritingPygtkApplications.xml: Actually add some
+	content to this section.
+
+	* tut/MiscellaneousWidgets.xml:
+	tut/UndocumentedWidgets.xml:
+	examples/message.py:
+	Add documentation and example for MessageDialog widget.
+
+2008-02-06  Gian Mario Tagliaretti  <gianmt gnome org>
+
+	* tut/CellRenderers.xml:
+	* tut/Introduction.xml: Fix a couple of broken links, Fixes #510830,
+	patch contributed by: techtonik.
+
 2006-08-01  Rafael Villar Burke  <pachi rvburke com>
 
 	* tut-it/ButtonWidget.xml: Added new translated file
diff --git a/Makefile b/Makefile
index 96aa1d1..06c0735 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,8 @@
 XSLFILES = common.xsl html.xsl tut-html-style.xsl \
 	pdf-style.xsl pdf.xsl devhelp.xsl
 
+CSSFILES = style.css
+
 TUTORIALXMLFILES = \
 tut/pygtk2-tut.xml \
 tut/Adjustments.xml \
@@ -43,6 +45,10 @@ tut/UndocumentedWidgets.xml \
 tut/WidgetOverview.xml \
 tut/ChangeLog.xml
 
+PICSTEMS= \
+singlewidget \
+twowidget
+
 TUTORIALLINKS = \
 pygtk2tutorial/images \
 pygtk2tutorial/examples \
@@ -98,16 +104,19 @@ ${ESOUTPUTDIR}/images \
 ${ESOUTPUTDIR}/examples \
 ${ESOUTPUTDIR}/figures
 
-tut-html: pygtk2tutorial ${TUTORIALLINKS} ${TUTORIALXMLFILES} ${XSLFILES}
+tut-html: pygtk2tutorial ${TUTORIALLINKS} ${TUTORIALXMLFILES} ${XSLFILES} \
+		${CSSFILES}
+	cp ${CSSFILES} pygtk2tutorial
 	xsltproc --nonet --xinclude -o pygtk2tutorial/ \
                  --stringparam gtkdoc.bookname pygtk2tutorial \
 		tut-html-style.xsl tut/pygtk2-tut.xml
 
+# symlinking isn't enough, dblatex wants the real ones
+# for images it's ok to symlink them here
 tut-pdf: pygtk2tutorial ${TUTORIALLINKS} ${TUTORIALXMLFILES} ${XSLFILES}
-	xsltproc --nonet --xinclude pdf-style.xsl tut/pygtk2-tut.xml \
-	| xmllint --format --nonet - > pygtk2-tut.fo
-	pdfxmltex pygtk2-tut.fo >output </dev/null
-	pdfxmltex pygtk2-tut.fo >output </dev/null
+	cp tut/*.xml pygtk2tutorial/ 
+	dblatex -V -t pdf -T db2latex -p pdf-dblatex.xsl -o pygtk2-tut.pdf \
+		pygtk2tutorial/pygtk2-tut.xml
 
 tut/ChangeLog.xml: tut/ChangeLog
 	(echo '<literallayout>'; \
@@ -125,7 +134,8 @@ tut/ChangeLog.xml: tut/ChangeLog
 
 tut-srcdist:
 	tar zcf pygtk2-tut.docbook.tgz ${TUTORIALXMLFILES} ${XSLFILES} \
-		tut/ChangeLog Makefile examples figures images
+		$(PICFILES) ${CSSFILES} tut/ChangeLog Makefile examples \
+		figures images
 
 tut-dist:
 	tar zhcf pygtk2tutorial.tgz pygtk2tutorial
@@ -135,26 +145,28 @@ pygtk2tutorial:
 
 pygtk2tutorial/images:
 	-mkdir pygtk2tutorial/images
-	-(cd pygtk2tutorial/images; ln -s ../../images/* .; rm CVS)
+	-(cd pygtk2tutorial/images; ln -s ../../images/* .)
 
 pygtk2tutorial/examples:
 	-mkdir pygtk2tutorial/examples
-	-(cd pygtk2tutorial/examples; ln -s ../../examples/* .; rm CVS)
+	-(cd pygtk2tutorial/examples; ln -s ../../examples/* .)
 
 pygtk2tutorial/figures:
 	-mkdir pygtk2tutorial/figures
-	-(cd pygtk2tutorial/figures; ln -s ../../figures/* .; rm CVS)
+	-(cd pygtk2tutorial/figures; ln -s ../../figures/* .)
+	for x in $(PICSTEMS); do pic2graph <tut/$$x.pic >pygtk2tutorial/figures/$$x.png; done
 
-tut-es-html: ${ESOUTPUTDIR} ${ESTUTORIALLINKS} ${ESTUTORIALXMLFILES} ${XSLFILES}
+tut-es-html: ${ESOUTPUTDIR} ${ESTUTORIALLINKS} ${ESTUTORIALXMLFILES} \
+		${XSLFILES} ${CSSFILES}
+	cp ${CSSFILES} ${ESOUTPUTDIR}
 	xsltproc --nonet --xinclude -o ${ESOUTPUTDIR}/ \
 		--stringparam gtkdoc.bookname  pygtk2tutorial \
 		tut-html-style.xsl tut-es/pygtk2-tut.xml
 
 tut-es-pdf: ${ESOUTPUTDIR} ${ESTUTORIALLINKS} ${ESTUTORIALXMLFILES} ${XSLFILES}
-	xsltproc --nonet --xinclude -o pygtk2-tut-es.fo pdf-style.xsl \
-		tut-es/pygtk2-tut.xml
-	pdfxmltex pygtk2-tut-es.fo >output </dev/null
-	pdfxmltex pygtk2-tut-es.fo >output </dev/null
+	cp tut-es/*.xml ${ESOUTPUTDIR}/ 
+	dblatex -t pdf -T db2latex -p pdf-dblatex.xsl -o pygtk2-tut-es.pdf \
+		${ESOUTPUTDIR}/pygtk2-tut.xml
 
 tut-es/ChangeLog.xml: tut-es/ChangeLog
 	(echo '<literallayout>'; \
@@ -172,7 +184,7 @@ tut-es/ChangeLog.xml: tut-es/ChangeLog
 
 tut-es-srcdist:
 	tar zcf pygtk2-tut-es.docbook.tgz ${ESTUTORIALXMLFILES} ${XSLFILES} \
-		tut-es/ChangeLog Makefile examples figures images
+		${CSSFILES} tut-es/ChangeLog Makefile examples figures images
 
 tut-es-dist: tut-html tut-pdf
 	cp pygtk2-tut-es.pdf ${ESOUTPUTDIR}/pygtk2tutorial-es.pdf
@@ -196,8 +208,6 @@ ${ESOUTPUTDIR}/figures:
 clean:
 	-rm -rf pygtk2tutorial ${ESOUTPUTDIR}
 	-rm -rf pygtk2tutorial.tgz pygtk2tutorial-es.tgz
-	-rm -rf pygtk2-tut.aux pygtk2-tut.fo pygtk2-tut.pdf pygtk2-tut.log \
-		pygtk2-tut.out output
-	-rm -rf	pygtk2-tut-es.aux pygtk2-tut-es.fo pygtk2-tut-es.pdf \
-		pygtk2-tut-es.log \
-		pygtk2-tut-es.out output.pdf
+	-rm -rf pygtk2-tut.pdf 
+	-rm -rf	pygtk2-tut-es.pdf 
+	-rm -f tut/ChangeLog.xml
diff --git a/2.0/README b/README
similarity index 100%
rename from 2.0/README
rename to README
diff --git a/2.0/examples/message.py b/examples/message.py
similarity index 100%
rename from 2.0/examples/message.py
rename to examples/message.py
diff --git a/html.xsl b/html.xsl
index 350f183..2008705 100644
--- a/html.xsl
+++ b/html.xsl
@@ -7,17 +7,11 @@
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                 version='1.0'>
 
-<xsl:param name="shade.verbatim" select="1"/>
+<xsl:param name="html.stylesheet">style.css</xsl:param>
 <xsl:param name="use.id.as.filename" select="1"/>
 <xsl:param name="chunk.fast" select="1"/>
 <xsl:param name="chunker.output.encoding" select="'utf-8'"/>
 
-<xsl:attribute-set name="shade.verbatim.style">
-  <xsl:attribute name="border">0</xsl:attribute>
-  <xsl:attribute name="bgcolor">#E0E0E0</xsl:attribute>
-  <xsl:attribute name="width">100%</xsl:attribute>
-</xsl:attribute-set>
-
 <xsl:param name="linenumbering.extension" select="1"/>
 <xsl:param name="variablelist.as.table" select="1"/>
 
@@ -50,26 +44,13 @@
         </table>
       </xsl:when>
       <xsl:when test="@role = 'properties' or @role = 'prototypes'">
-  	<xsl:choose>
-    	  <xsl:when test="$shade.verbatim != 0">
-            <table width="100%" xsl:use-attribute-sets="shade.verbatim.style">
-              <tr>
-                <td valign="top">
-                  <xsl:apply-templates select="child::*[local-name(.)!='attribution']"/>
-                </td>
-              </tr>
-            </table>
-          </xsl:when>
-	  <xsl:otherwise>
-            <table width="100%" border="0">
-              <tr>
-                <td valign="top">
-                  <xsl:apply-templates select="child::*[local-name(.)!='attribution']"/>
-                </td>
-              </tr>
-            </table>
-          </xsl:otherwise>
-        </xsl:choose>
+        <table width="100%" border="0">
+          <tr>
+            <td valign="top">
+              <xsl:apply-templates select="child::*[local-name(.)!='attribution']"/>
+            </td>
+          </tr>
+        </table>
       </xsl:when>
       <xsl:otherwise>
         <blockquote class="{local-name(.)}">
diff --git a/2.0/pdf-dblatex.xsl b/pdf-dblatex.xsl
similarity index 100%
rename from 2.0/pdf-dblatex.xsl
rename to pdf-dblatex.xsl
diff --git a/2.0/style.css b/style.css
similarity index 100%
rename from 2.0/style.css
rename to style.css
diff --git a/tut-es/ComboBoxAndComboBoxEntry.xml b/tut-es/ComboBoxAndComboBoxEntry.xml
index 3cf6d4a..91e164a 100644
--- a/tut-es/ComboBoxAndComboBoxEntry.xml
+++ b/tut-es/ComboBoxAndComboBoxEntry.xml
@@ -62,9 +62,15 @@ anteriores funciones y m
         </mediaobject>
       </figure>
 
-      <para>Desafortunadamente, los desarrolladores de <literal>GTK</literal>+ no proporcionan
-un método conveniente para obtener el texto activo. Ese parecería un método útil, pero será
-necesario crear uno propio simila a:</para>
+      <para>Para obtener el texto activo se puede usar el método:</para>
+
+      <programlisting>
+  texto = combobox.get_active_text()
+      </programlisting>
+
+      <para>Sin embargo, hasta la versión 2.6 no se proporciona en
+          <literal>GTK</literal>+ un método cómodo para obtener el texto activo.
+          Para ello se podría usar una implementación similar a:</para>
 
       <programlisting>
   def get_active_text(combobox):
diff --git a/tut-es/TreeViewWidget.xml b/tut-es/TreeViewWidget.xml
index 36aa91e..507449f 100644
--- a/tut-es/TreeViewWidget.xml
+++ b/tut-es/TreeViewWidget.xml
@@ -1073,7 +1073,7 @@ ejemplo:</para>
   </sect1>
 
   <sect1 id="sec-TreeViewDragAndDrop">
-    <title>Arrastra y Soltar en TreeView</title>
+    <title>Arrastrar y Soltar en TreeView</title>
 
     <sect2 id="DragDropReordering">
       <title>Reordenación mediante Arrastrar y Soltar</title>
diff --git a/tut/CellRenderers.xml b/tut/CellRenderers.xml
index e546e5d..fe83964 100644
--- a/tut/CellRenderers.xml
+++ b/tut/CellRenderers.xml
@@ -668,7 +668,7 @@ string.</para>
 
     <programlisting>
   ...
-  def obj_id_str(treeviewcolumn, cell_renderer, model, iter):
+  def obj_id_str(treeviewcolumn, cell, model, iter):
       pyobj = model.get_value(iter, 0)
       cell.set_property('text', str(pyobj))
       return
@@ -679,6 +679,7 @@ string.</para>
   win.add(treeview)
   cell = CellRendererText()
   tvcolumn = gtk TreeViewColumn('Object ID', cell)
+  tvcolumn.set_cell_data_func(cell, obj_id_str)
   treeview.append_column(tvcolumn)
   iter = treestore.append(None, [win])
   iter = treestore.append(iter, [treeview])
@@ -776,9 +777,9 @@ program in action:</para>
 setting the "markup" property) instead of a plain text string to encode
 various text attributes and provide a rich text display with multiple font
 style changes. See the <ulink
-url="http://www.pygtk.org/pygtk2reference/pango-markup.html";>Pango
+url="http://www.pygtk.org/pygtk2reference/pango-markup-language.html";>Pango
 Markup</ulink> reference in the <ulink
-url="http://www.pygtk.org/pygtk2reference";>PyGTK Reference Manual</ulink>
+url="http://www.pygtk.org/pygtk2reference/";>PyGTK Reference Manual</ulink>
 for details on the Pango markup language.</para>
 
     <para>The following code fragment illustrates the use of the
diff --git a/tut/ChangeLog b/tut/ChangeLog
index 212f50f..7244d56 100644
--- a/tut/ChangeLog
+++ b/tut/ChangeLog
@@ -1,3 +1,23 @@
+2009-02-24  John Finlay  <finlay moeraki com>
+
+	* Credits.xml (url): Add credit to Charles Wilson. Rearrange the
+	credits and consolidate PyGTK credits.
+
+	* TipsForWritingPygtkApplications.xml: Add section in Tips from
+	Charles Wilson "How to Separate Callback Methods From Signal
+	Handlers"
+
+2008-03-28  John Finlay  <finlay moeraki com>
+
+	* CellRenderers.xml: Fix code fragment for set_cell_data_func
+	example. (Yotam Medini)
+
+2007-03-09  Rafael Villar Burke  <pachi rvburke com>
+
+	* tut/ComboBoxAndComboboxEntry.xml: Add reference to new (2.6)
+	get_active_text() method Fixes #364187.
+	* tut-es/ComboBoxAndComboBoxEntry.xml: fix same problem
+
 2006-03-02  John Finlay  <finlay moeraki com>
 
 	* pygtk2-tut.xml: Bump revision number and date.
diff --git a/tut/ComboBoxAndComboBoxEntry.xml b/tut/ComboBoxAndComboBoxEntry.xml
index 695b6ee..602c805 100644
--- a/tut/ComboBoxAndComboBoxEntry.xml
+++ b/tut/ComboBoxAndComboBoxEntry.xml
@@ -62,9 +62,15 @@ operation:</para>
         </mediaobject>
       </figure>
 
-      <para>Unfortunately, the <literal>GTK</literal>+ developers did not
-provide a convenience method to retrieve the active text. That would seem to
-be a useful method. You'll have to create your own similar to:</para>
+      <para>The active text can be retrieved using the method:</para>
+
+        <programlisting>
+  text = combobox.get_active_text()
+        </programlisting>
+
+      <para>Prior to version 2.6, the <literal>GTK</literal>+ developers
+          did not provide such a convenience method to retrieve the active text,
+          so you'd have to create your own implementation, similar to:</para>
 
       <programlisting>
   def get_active_text(combobox):
@@ -75,6 +81,7 @@ be a useful method. You'll have to create your own similar to:</para>
       return model[active][0]
 </programlisting>
 
+
       <para>The index of the active item is retrieved using the method:</para>
 
       <programlisting>
diff --git a/tut/Credits.xml b/tut/Credits.xml
index daee513..233211c 100644
--- a/tut/Credits.xml
+++ b/tut/Credits.xml
@@ -6,29 +6,6 @@
   <chapter id="ch-Credits">
     <title>Credits</title>
 <!-- ===================================================================== -->
-  <sect1 id="sec-PyGTKCredits">
-    <title>PyGTK Credits</title>
-
-    <para>Thanks to:</para>
-
-    <itemizedlist>
-      <listitem>
-        <simpara>Nathan Hurst for the <classname>Plugs</classname> and
-<classname>Sockets</classname> section.</simpara>
-      </listitem>
-      <listitem>
-        <simpara>Alex Roitman for the <classname>FileChooser</classname>
-section.</simpara>
-      </listitem>
-      <listitem>
-        <simpara>Steve George for the example program illustrating editable
-<classname>CellRendererText</classname> and activatable
-<classname>CellRendererToggle</classname>.</simpara>
-      </listitem>
-    </itemizedlist>
-
-  </sect1>
-
   <sect1 id="sec-OriginalGTK+Credits">
     <title>Original GTK+ Credits</title>
 
@@ -129,4 +106,42 @@ DAChaplin msn com</para>
 
     <para>Thanks.</para>
   </sect1>
+
+  <sect1 id="sec-PyGTKTutorialCredits">
+    <title>PyGTK Tutorial Credits</title>
+
+     <para>This tutorial was originally adapted from the GTK+
+     documentation by John Finlay.</para>
+
+    <para>Thanks to:</para>
+
+    <itemizedlist>
+      <listitem>
+        <simpara>Nathan Hurst for the <classname>Plugs</classname> and
+<classname>Sockets</classname> section.</simpara>
+      </listitem>
+      <listitem>
+        <simpara>Alex Roitman for the <classname>FileChooser</classname>
+section.</simpara>
+      </listitem>
+      <listitem>
+        <simpara>Steve George for the example program illustrating editable
+<classname>CellRendererText</classname> and activatable
+<classname>CellRendererToggle</classname>.</simpara>
+      </listitem>
+      <listitem>
+        <simpara>Charles Wilson for the "How to Separate Callback Methods
+        From Signal Handlers" section in the "Tips For Writing PyGTK
+        Applications" chapter.</simpara>
+      </listitem>
+    </itemizedlist>
+
+     <para>Much of <xref
+     linkend="sec-TheoryOfPackingBoxes"/> was adapted from the PyGTK
+     FAQ item 12.2 <citetitle>How does packing work (or how do I get
+     my widget to stay the size I want)</citetitle> as it existed on
+     21 October 2008, And had been originally written by Christian
+     Reis.</para>
+
+  </sect1>
   </chapter>
diff --git a/tut/GettingStarted.xml b/tut/GettingStarted.xml
index 0a3c4a4..6a59517 100644
--- a/tut/GettingStarted.xml
+++ b/tut/GettingStarted.xml
@@ -334,16 +334,10 @@ example is:</para>
 <programlisting>
   handler_id = object.connect_object(name, func, slot_object)
 </programlisting>
-      <para><methodname>connect_object</methodname>() is the same as
-<methodname>connect</methodname>() except a callback function only uses one
-argument and a callback method, two arguments:</para>
-
-<programlisting>
-  def callback_func(object)
-  def callback_meth(self, object)
-</programlisting>
-
-      <para>where <parameter>object</parameter> is usually a widget.
+      <para><methodname>connect_object</methodname>() is like
+<methodname>connect</methodname>(), except that it invokes
+<parameter>func</parameter> on <parameter>slot_object</parameter>,
+where <parameter>slot_object</parameter> is usually a widget.
 <methodname>connect_object</methodname>() allows the PyGTK widget methods
 that only take a single argument (<parameter>self</parameter>) to be used as
 signal handlers.</para>
@@ -659,6 +653,12 @@ it. Although with such a simple example, you'd never notice.</para>
     self.window.show()
 </programlisting>
 
+<para>Widgets also have a <methodname>hide()</methodname> that is the
+opposite of <methodname>show()</methodname>.  It doesn't actually
+destroy the widget, but it removes the widget renderining from your
+display.  This can be reversed with another
+<methodname>show()</methodname> call.</para>
+
       <para>Lines 73-75 define the <methodname>main</methodname>() method
 which calls the <function>gtk.main</function>() function</para>
 
diff --git a/tut/Introduction.xml b/tut/Introduction.xml
index 71b1562..4bbb49a 100644
--- a/tut/Introduction.xml
+++ b/tut/Introduction.xml
@@ -141,7 +141,7 @@ describe how to compile or install Python, GTK+ or PyGTK.</para>
 
 <para>This document is a "work in progress". Please look for updates on
 <ulink
-url="http://www.pygtk.org/pygtktutorial";>www.pygtk.org</ulink>.</para>
+url="http://www.pygtk.org/pygtk2tutorial/";>www.pygtk.org</ulink>.</para>
 
 <para>I would very much like to hear of any problems you have learning PyGTK
 from this document, and would appreciate input as to how it may be improved.
@@ -154,12 +154,12 @@ Bugzilla may help.</para>
 
   <para>The PyGTK 2.0 Reference Manual is available at
 <ulink
-url="http://www.pygtk.org/pygtkreference";>http://www.pygtk.org/pygtkreference</ulink>. It describes in detail the PyGTK classes.</para>
+url="http://www.pygtk.org/reference.html";>http://www.pygtk.org/reference.html</ulink>. It describes in detail the PyGTK classes.</para>
 
   <para>The PyGTK website (<ulink
 url="http://www.pygtk.org";>www.pygtk.org</ulink>) contains other resources
 useful for learning about PyGTK including a link to the extensive <ulink
-url="http://www.async.com.br/faq/pygtk/";>FAQ</ulink> and other articles and
+url="http://faq.pygtk.org/";>FAQ</ulink> and other articles and
 tutorials and an active maillist and IRC channel (see <ulink
 url="http://www.pygtk.org/feedback.html";>www.pygtk.org</ulink> for
 details).</para>
diff --git a/tut/MiscellaneousWidgets.xml b/tut/MiscellaneousWidgets.xml
index 7f625b9..38353bd 100644
--- a/tut/MiscellaneousWidgets.xml
+++ b/tut/MiscellaneousWidgets.xml
@@ -808,6 +808,68 @@ horizontal boxes in the two areas doesn't give you enough control for your
 application, then you can simply pack another layout widget into the boxes
 provided. For example, you could pack a table into the vertical box.</para>
 
+      <sect2 id="sec-MessageDialogs">
+        <title>Message Dialogs</title>
+
+<para>A message dialog is a specialization of the already rather simple *Dialog*
+widget for displaying standardized error, question, and information
+popups.  Invoke it like this:</para>
+
+      <programlisting>
+message = gtk.MessageDialog(parent=None, 
+                            flags=0, 
+                            type=gtk.MESSAGE_INFO, 
+                            buttons=gtk.BUTTONS_NONE, 
+                            message_format=None)
+</programlisting>
+
+<para>The <parameter>type</parameter> flag selects a stock icon to be 
+displayed in the message:</para>
+
+      <programlisting>
+MESSAGE_INFO - information message
+MESSAGE_WARNING - warning (or recoverable error) message
+MESSAGE_QUESTION - question that can be answered with a button click
+MESSAGE_ERROR - error message
+</programlisting>
+
+<para>To set the text for the message, feed it a Pango markup string.  As
+a matter of style, you probably want to stick to relatively terse,
+one-sentence messages when using this widget.</para>
+
+      <programlisting>
+message.set_markup("Sample message, could contain pango markup")
+</programlisting>
+
+<para>Here's an example program, <ulink
+url="examples/message.py"><command>message.py</command></ulink></para>
+
+      <programlisting>
+     1	#!/usr/bin/env python
+       
+     2	# message.py -- example program illustrating use of message dialog widget 
+       
+     3	import pygtk
+     4	pygtk.require('2.0')
+     5	import gtk
+       
+     6	if __name__ == "__main__":
+     7	    message = gtk.MessageDialog(type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK)
+     8	    message.set_markup("An example error popup.")
+     9	    message.run()
+</programlisting>
+
+<para>We used <methodname>run()</methodname> here to make the dialog
+modal; we could have achieved the same result by setting
+<parameter>flags</parameter> to <constant>DIALOG_MODAL</constant>, and
+doing this instead:</para>
+
+      <programlisting>
+    message.show()
+    gtk.main()
+</programlisting>
+
+      </sect2>
     </sect1>
 
 <!-- ===================================================================== -->
diff --git a/tut/PackingWidgets.xml b/tut/PackingWidgets.xml
index 3286ac0..6c88cf3 100644
--- a/tut/PackingWidgets.xml
+++ b/tut/PackingWidgets.xml
@@ -40,19 +40,88 @@ another container or a widget. In fact, many widgets are actually containers
 themselves, including the button, but we usually only use a label inside a
 button.</para>
 
-    <para>By using these calls, GTK knows where you want to place your
-widgets so it can do automatic resizing and other nifty things. There are
-also a number of options as to how your widgets should be packed. As you can
-imagine, this method gives us a quite a bit of flexibility when placing and
-creating widgets.</para>
+<para>You may find when working with containers that the size (and
+aspect ratio) of your widget isn't quite what you would expect. That's
+an intentional consequence of the GTK+ box model.  The size of any
+given widget is determined both by by how it packs among the widgets
+around it and whether or not its container offers it the possibility
+to expand and fill space available to it.</para>
+
+<para>if you have a container a single child, this child will take up
+all its space minus its border:</para>
+
+      <figure id="singlewidget">
+	<title>Packing: A Single Widget in a Container</title>
+	<mediaobject>
+	  <imageobject>
+	    <imagedata fileref="figures/singlewidget.png" format="png" align="center"/>
+	  </imageobject>
+	</mediaobject>
+      </figure>
+
+<para>If you have a container (say a VBox or HBox) with two (or
+more) children, they will fight<footnote><para>A cute analogy; in reality
+fill, expansion, requested sizes, widget expansion semantics,
+container packing semantics, electron spins and lunar cycles are
+computed to determine how much space each widget wins.</para></footnote> to
+determine who takes up more space:</para>
+
+      <figure id="twowidget">
+	<title>Packing: Two Widgets in a Container</title>
+	<mediaobject>
+	  <imageobject>
+	    <imagedata fileref="figures/twowidget.png" format="png" align="center"/>
+	  </imageobject>
+	</mediaobject>
+      </figure>
 
+<para>How much each one actually gets is determined by:</para>
+
+<itemizedlist>
+<listitem><para>the default and requested sizes of the widgets, which
+normally depends on their contents (for labels, in
+particular).</para></listitem>
+
+<listitem><para>the expand and fill arguments supplied to
+<methodname>add()</methodname> or
+<methodname>pack_start</methodname>/<methodname>pack_end()</methodname>,
+all three of which we will describe in more detail later in this
+chapter:</para>
+
+<itemizedlist>
+<listitem><para>
+<parameter>expand</parameter>=<constant>True</constant> means "I will
+fight for space"
+</para></listitem>
+<listitem><para>
+<parameter>expand</parameter>=<constant>False</constant> means "I don't want more space"</para></listitem>
+<listitem><para>
+<parameter>fill</parameter>=<constant>True</constant> means "If I got
+more space, I will occupy it with my content"
+</para></listitem>
+<listitem><para>
+<parameter>fill</parameter>=<constant>False</constant> means "If I got
+more space, leave it blank"
+</para></listitem>
+</itemizedlist>
+</listitem>
+</itemizedlist>
+
+<para>This is important to understand when assembling your interfaces,
+and is the most peculiar thing about GTK+ programming to a newbie;
+although the packing-based widget geometry is more complex to
+understand initially than fixed-width layouts, it is superior
+because GTK+ windows actually resize properly.</para>
+
+<para>To get an intuitive grasp of the box model, spend some time
+experimenting with the "packing" tab in Glade.</para>
     </sect1>
 
 <!-- ===================================================================== -->
     <sect1 id="sec-DetailsOfBoxes">
       <title>Details of Boxes</title>
 
-      <para>Because of this flexibility, packing boxes in GTK can be
+      <para>Because of all this flexibility, packing boxes in GTK can be
 confusing at first. There are a lot of options, and it's not immediately
 obvious how they all fit together. In the end, however, there are basically
 five different styles. <xref linkend="packbox1fig"/> illustrates the result
@@ -86,7 +155,7 @@ into; the first argument is the <parameter>child</parameter> object to be
 packed. The objects will all be buttons for now, so we'll be packing buttons
 into boxes.</para>
 
-      <para>The <parameter>expand</parameter> argument to
+      <para>As previously noted, the <parameter>expand</parameter> argument to
 <methodname>pack_start</methodname>() and
 <methodname>pack_end</methodname>() controls whether the widgets are laid
 out in the box to fill in all the extra space in the box so the box is
@@ -98,10 +167,11 @@ the box, and the same effect could be achieved by using only one of
 <methodname>pack_start</methodname>() or
 <methodname>pack_end</methodname>().</para>
 
-      <para>The <parameter>fill</parameter> argument to the pack methods
-control whether the extra space is allocated to the objects themselves
-(<literal>True</literal>), or as extra padding in the box around these
-objects (<literal>False</literal>). It only has an effect if the expand
+      <para>As previously noted, the <parameter>fill</parameter>
+argument to the pack methods control whether the extra space is
+allocated to the objects themselves (<literal>True</literal>), or as
+extra padding in the box around these objects
+(<literal>False</literal>). It only has an effect if the expand
 argument is also <literal>True</literal>.</para>
 
       <para>Python allows a method or function to be defined with default
diff --git a/tut/TipsForWritingPygtkApplications.xml b/tut/TipsForWritingPygtkApplications.xml
index 319cb03..3d8093b 100644
--- a/tut/TipsForWritingPygtkApplications.xml
+++ b/tut/TipsForWritingPygtkApplications.xml
@@ -11,4 +11,442 @@ guidelines and hints to creating good PyGTK applications. Currently this
 section is very short, but I hope it will get longer in future editions of
 this tutorial.</para>
 
-  </chapter>
+<!-- ===================================================================== -->
+    <sect1>
+    <title>The user should drive the interface, not the reverse</title>
+
+<para>PyGTK, like other toolkits, gives you ways of invoking widgets,
+such as the <constant>DIALOG_MODAL</constant> flag passed to dialogs,
+that require a response from the user before the rest of the
+application can continue.  In Python, as in other languages, it is
+good style to use modal interface elements as little as possible.</para>
+
+<para>Every modal interaction is a place where your application is
+forcing a particular workflow on the user. While this is sometime
+unavoidable, as a general rule it is backwards; the application should
+be adapting itself to the user's preferred workflow instead.</para>
+
+<para>A particularly common case of this, which ought to be much less so 
+is confirmation prompts. Every confirmation prompt is a place where
+you should support an undo operation instead; the GIMP, the
+application GTK was originally built for, avoids many operations that
+would otherwise requite a stop-and-check with the user by having 
+an undo command that can unwind any operation it does.</para>
+
+    </sect1>
+<!-- ===================================================================== -->
+    <sect1>
+    <title>Separate your data model from your interface</title>
+
+<para>Python's flexible, duck-typed object system lowers the cost of
+architectural options that are more difficult to exercise in more
+rigid languages (yes, we <emphasis>are</emphasis> thinking of C++).
+One of these is carefully separating your data model (the classes and
+data structures that represent whatever state your application is
+designed to manipulate) from your controller (the classes that
+implement your user interface.</para>
+
+<para>In Python, a design pattern that frequently applies is to have
+one master editor/controller class that encapsulates your user interface
+(with, possibly, small helper classes for stateful widgets) and one
+master model class that encapsulates your application state (probably
+with some members that are themselves instances of small data-representation
+classes).  The controller calls methods in the model to do all its
+data manipulation; the model delegates screen-painting and
+input-event processing to the controller.</para>
+
+<para>Narrowing the interface between model and controller makes it
+easier to avoid being locked into early decisions about either part
+by adhesions with the other one.  It also makes downstream 
+maintainance and bug diagnosis easier.</para>
+    </sect1>
+<!-- ===================================================================== -->
+<sect1>
+  <title>How to Separate Callback Methods From Signal Handlers</title>
+  <sect2>
+    <title>Overview</title>
+
+    <para>
+      You do not have to store all of your callback methods in one main
+      program file.  You can separate them into classes of their own, in
+      separate files. This way your main program can derive the methods from
+      those classes using inheritance. You end up having all the original
+      functionality with the added benifits of easier maintenance, code
+      reusability, and smaller file sizes, which means less of a burden for
+      text editors.
+    </para>
+  </sect2>
+
+  <sect2>
+    <title>Inheritance</title>
+
+    <para>
+      Inheritance is a way to reuse code. A class can inherit all the
+      functionality of other classes, and the nice thing about inheritance
+      is that we can use it to divide a huge program into logical groups of
+      smaller, more maintainable pieces.
+    </para>
+
+    <para>
+      Now lets spend a second on terminology. A derived class, some call
+      this a subclass or a child class, is a class that derives some of its
+      functionality from other classes.
+
+      A base class, some call it a superclass or a parent class, is what the
+      derived class inherits from.
+    </para>
+
+    <para>
+      Below is a short example to help you become familiar with
+      inheritance. You can try this out in the python interpreter to gain
+      some first hand experience.
+    </para>
+
+    <para>
+      Create two base classes:
+    </para>
+
+    <programlisting>
+class base1:
+   base1_attribute = 1
+   def base1_method(self):
+     return "hello from base class 1"
+
+class base2:
+   base2_attribute = 2
+   def base2_method(self):
+     return "hello from base class 2"
+    </programlisting>
+
+    <para>
+      Then create a derived class that inherits from these two base classes:
+    </para>
+
+    <programlisting>
+class derived(base1, base2):  #a class derived from two base classes
+   var3 = 3                     
+    </programlisting>
+
+    <para>
+      Now the derived class has all the functionality of the base classes. 
+    </para>
+
+    <programlisting>
+x = derived()        # creates an instance of the derived class
+x.base1_attribute    # 1
+x.base2_attribute    # 2
+x.var3               # 3
+x.base1_method()     # hello from base class 1
+x.base2_method()     # hello from base class 2
+    </programlisting>
+
+    <para>
+      The object called x has the ability to access the variables and
+      methods of the base classes because it has inherited their
+      functionality.  Now lets apply this concept of inheritance to a PyGTK
+      application.
+    </para>
+
+  </sect2>
+
+
+  <sect2>
+    <title>Inheritance Applied To PyGTK</title>
+
+    <para>
+      Create a file called gui.py, then copy this code into it.
+    </para>
+
+    <programlisting>
+#A file called: gui.py
+
+import pygtk                                                  
+import gtk                                                   
+
+# Create a class definition called gui                                    
+class gui:
+  #                                                     
+  #          CALLBACK METHODS
+  #------------------------------------                                                                                                
+  def open(self, widget):                              
+    print "opens stuff"                                       
+  def save(self, widget):                              
+    print "save stuff"                                        
+  def undo(self, widget):                              
+    print "undo stuff"                                       
+  def destroy(self, widget):
+    gtk.main_quit()
+         
+                                                        
+  def __init__(self): 
+    #
+    #        GUI CONSTRUCTION CODE
+    #-----------------------------------------------
+    self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+    self.window.show()                                                              
+    self.vbox1 = gtk.VBox(False, 25)
+    self.window.add(self.vbox1)
+    open_button = gtk.Button(label="Open Stuff")
+    open_button.set_use_stock(True)
+    self.vbox1.pack_start(open_button, False, False, 0)
+    open_button.show() 
+    save_button = gtk.Button(label="Save Stuff")
+    self.vbox1.pack_start(save_button, False, False, 0)
+    save_button.show()
+    undo_button = gtk.Button(label="Undo")
+    self.vbox1.pack_start(undo_button, False, False, 0)
+    undo_button.show()
+    self.vbox1.show()
+    #
+    #        SIGNAL HANDLERS
+    #------------------------------------------------                                                        
+    open_button.connect("clicked", self.open)          
+    save_button.connect("clicked", self.save)           
+    undo_button.connect("clicked", self.undo) 
+    self.window.connect("destroy", self.destroy)          
+                                                              
+  def main(self):                                             
+   gtk.main()                                                 
+                                                              
+if __name__ == "__main__":                                    
+ gui_instance = gui()       # create a gui object             
+ gui_instance.main()        # call the main method         
+    </programlisting>
+
+    <para>
+      If your run this program you will find it is just a simple window with
+      some buttons. As the program is organized right now, all of the code
+      is in one single file.  But in a moment, you will find out how to
+      break that program up into multiple files.  The idea is to take those
+      four callback methods out of the gui class and put them into classes
+      of their own, in separate files. Now if you had hundreds of callback
+      methods you would try and group them in some logical way, for example,
+      you might put all of your methods that deal with input/output into the
+      same class, and you would make other classes for other groups of
+      methods as well.
+    </para>
+
+    <para>
+      The first thing we have to do is make some classes for the methods in
+      the gui.py file. Create three new text files, and name them io.py,
+      undo.py, and destroy.py, and put these files in the same directory as
+      the gui.py file.  Copy the code below into the io.py file.
+    </para>
+
+    <programlisting>
+class io:                                                       
+  def open(self, widget):                                  
+    print "opens stuff"                                          
+                                      
+  def save(self, widget):                                  
+    print "save stuff"                                           
+    </programlisting>
+
+    <para>
+      These are the two callback methods, open and save, from the gui.py
+      program.  Copy the next block of code into the undo.py file.
+    </para>
+
+    <programlisting>
+class undo:                                                      
+  def undo(self, widget):                                  
+    print "undo stuff" 
+    </programlisting>
+
+    <para> 
+      This is the undo_method from gui.py.  And finally, copy the code below
+      into destroy.py.
+    </para>
+
+    <programlisting>
+import gtk
+
+class destroy:
+  def destroy(self, widget):
+    gtk.main_quit()                                                            
+    </programlisting>
+
+    <para>
+      Now all the methods are separated into classes of their own.
+    </para>
+
+    <graphic fileref="images/important.gif"></graphic>
+    <important>
+      <para>
+        In your future programs you will want to import things like gtk,
+        pango, os ect...  into your derived class(the one with all of your
+        gui initialization code), but also, remember to import any modules
+        or classes you need into your base classes too. Sometimes you might
+        create an instance of a gtk widget in a base class method, in that
+        case import gtk.
+      </para>
+
+      <para>
+        This is just an example of a base class where you would be required
+        to import gtk.
+      </para>
+
+      <programlisting>
+  import gtk                                                        
+                                                                           
+  class Font_io                                                     
+    def Font_Chooser(self,widget):                                  
+      self.fontchooser = gtk.FontSelectionDialog("Choose Font")                                  
+      self.fontchooser.show()    
+      </programlisting>
+
+      <para>
+        Notice it defines a gtk widget, a font selection dialog. You would
+        normally import gtk in your main class(the derived class) and
+        everything would be ok. But the second you take this Font_Chooser
+        method out of your main class and put it into a class of its own,
+        and then try to inherit from it, you would find you get an error.
+        In this case, you would not even see any error until you were
+        running the program.  But when you try to use the Font_Chooser, you
+        would find that gtk is not defined, even though you have imported it
+        in your derived class. So just remember that when you create base
+        classes, you need to add their proper imports too.
+      </para>
+    </important>
+
+    <para>
+      With your three classes in three separate py files, you now need to
+      change the code in the gui.py file in three ways.
+    </para>
+
+    <orderedlist numberation="arabic"> 
+      <listitem><para>Import the classes you have created.</para></listitem>
+      <listitem><para>Change your class definition.</para></listitem>
+      <listitem><para>Delete your callback methods.</para></listitem>
+    </orderedlist>
+
+    <para>
+      The updated code below shows how to do this.
+    </para>
+
+
+    <programlisting>
+#A file called:  gui.py
+#(updated version)
+#(with multiple inheritance)
+
+import pygtk                                                  
+import gtk  
+                       
+from io import file_io                       #                                
+from undo import undo                        # 1. Import Your Classes
+from destroy import destroy                  #
+
+# Create a class definition called gui                                    
+class gui(io, undo, destroy):                # 2. Changed Class Definition
+                                             # 3. Deleted Callbacks
+  def __init__(self): 
+    #
+    #        GUI CONSTRUCTION CODE
+    #-----------------------------------------------
+    self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+    self.window.show()
+    self.vbox1 = gtk.VBox(False, 25)
+    self.window.add(self.vbox1)
+    open_button = gtk.Button(label="Open Stuff")
+    open_button.set_use_stock(True)
+    self.vbox1.pack_start(open_button, False, False, 0)
+    open_button.show() 
+    save_button = gtk.Button(label="Save Stuff")
+    self.vbox1.pack_start(save_button, False, False, 0)
+    save_button.show()
+    undo_button = gtk.Button(label="Undo")
+    self.vbox1.pack_start(undo_button, False, False, 0)
+    undo_button.show()
+    self.vbox1.show()
+    #
+    #        SIGNAL HANDLERS
+    #------------------------------------------------
+    open_button.connect("clicked", self.open_method)          
+    save_button.connect("clicked", self.save_method)           
+    undo_button.connect("clicked", self.undo_method) 
+    self.window.connect("destroy", self.destroy)          
+                                                              
+  def main(self):                                             
+   gtk.main()                                                 
+                                                              
+if __name__ == "__main__":                                    
+ gui_instance = gui()       # create a gui object             
+ gui_instance.main()        # call the main method
+    </programlisting>
+
+    <para>
+      These three lines are new:
+    </para>
+
+    <programlisting>
+       from io import io                                   
+       from undo import undo                                          
+       from destroy import destroy     
+    </programlisting>
+
+    <para>
+      The import statements are of the form:
+    </para>
+
+    <programlisting>
+       from [filename of your class file] import [class name]
+    </programlisting>
+
+    <para>
+      Here is the class definition change:
+    </para>
+
+    <programlisting>
+       class gui(io, undo, destroy):
+    </programlisting>
+
+    <para>
+      The names of the base classes go between the parenthesis in the class
+      definition.  Now the gui class has become a derived class, and is able
+      to use all the attributes and methods defined in its base
+      classes. Also, the gui class is inheriting from multiple classes(two
+      or more), this is known as multiple inheritance.
+    </para>
+
+    <para>
+      Now change the gui.py file to the updated version and run the program
+      again.  You will notice it works exactly the same, except now all the
+      callback methods are in separate classes, being inherited by the gui
+      class.
+    </para>
+
+    <para>
+      There is just one other matter of interest to take note of.  As long
+      as your gui.py program and your base class files are all in the same
+      directory, everything will work just fine. But if you want to create
+      another directory inside there called classes, in which to organize
+      your files of base classes, then you will need to add two more lines
+      of code with the rest of your import statements in gui.py, like this:
+    </para>
+
+    <programlisting>
+        import sys
+        sys.path.append("classes")
+    </programlisting>
+
+    <para>
+      where classes is the name of the directory you store your classes
+      in. This lets Python know where to look for your classes.  Try it
+      out. Just make a directory called classes in the directory where you
+      have the gui.py program. Then put your three base class files into
+      this classes directory.  Now add the two lines of code show above to
+      the top of the gui.py file.  And thats it!
+    </para>
+
+    <para>
+      One final note for those that use py2exe for compiling python
+      programs. Put your base classes in your Python directory, then py2exe
+      will included them in the compiled version of your program just like
+      any other Python module.
+    </para>
+
+  </sect2> 
+
+</sect1>
+</chapter>
diff --git a/tut/UndocumentedWidgets.xml b/tut/UndocumentedWidgets.xml
index 5421be9..e69c064 100644
--- a/tut/UndocumentedWidgets.xml
+++ b/tut/UndocumentedWidgets.xml
@@ -71,13 +71,6 @@ benefit from your time.</para>
     </sect1>
 
 <!-- ===================================================================== -->
-    <sect1 id="sec-MessageDialog">
-      <title>Message Dialog</title>
-      <para></para>
-
-    </sect1>
-
-<!-- ===================================================================== -->
     <sect1 id="sec-GammaCurve">
       <title>Gamma Curve</title>
       <para></para>
diff --git a/2.0/tut/singlewidget.pic b/tut/singlewidget.pic
similarity index 100%
rename from 2.0/tut/singlewidget.pic
rename to tut/singlewidget.pic
diff --git a/2.0/tut/twowidget.pic b/tut/twowidget.pic
similarity index 100%
rename from 2.0/tut/twowidget.pic
rename to tut/twowidget.pic



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]