<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>learning python &#187; WordPy</title>
	<atom:link href="http://www.learningpython.com/category/python/wordpy/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.learningpython.com</link>
	<description>one man's journey into python...</description>
	<lastBuildDate>Wed, 21 Sep 2011 03:08:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>WordPy 0.2 &#8211; Using XML to Save and Load Data</title>
		<link>http://www.learningpython.com/2006/10/24/wordpy-02-using-xml-to-save-and-load-data/</link>
		<comments>http://www.learningpython.com/2006/10/24/wordpy-02-using-xml-to-save-and-load-data/#comments</comments>
		<pubDate>Wed, 25 Oct 2006 02:22:52 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[glade]]></category>
		<category><![CDATA[gui]]></category>
		<category><![CDATA[PyGTK]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[reference]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[WordPy]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=41</guid>
		<description><![CDATA[All right, so we have our base WordPy application running, so let&#8217;s try to extend it a bit more by letting you load and save blog posts to and from an xml file. Please note that this tutorial simply shows one method of saving and loading data using xml, there are many different methods and [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2006%2F10%2F24%2Fwordpy-02-using-xml-to-save-and-load-data%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2006%2F10%2F24%2Fwordpy-02-using-xml-to-save-and-load-data%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>All right, so we have our base WordPy application running, so let&#8217;s try to extend it a bit more by letting you load and save blog posts to and from an xml file.  Please note that this tutorial simply shows one method of saving and loading data using xml, there are many different methods and this method was chosen for its simplicity.</p>
<p>If you are unfamiliar with the <a href="http://www.learningpython.com/2006/08/19/wordpress-python-library/">first WordPy tutorial</a> you should probably read it fist in order to have a better understanding of some of what happens in this tutorial. </p>
<p>You can download the complete code for this tutorial <a href="http://www.learningpython.com/sources/WordPy_0_2.tar.gz">here</a>.</p>
<h2>The GUI</h2>
<p>The first thing we need to-do is open up the wordpy glade project and make some changes:</p>
<ol>
<li>We&#8217;ll start off by adding another item to our VBox in Glade.  You can do this by holding down shift and clicking on the WordPy window until you see the GTKVBox come up in the properties window.  Then simply change it&#8217;s size value from 4 to 5.</li>
<li>In the empty space add a menu bar.  Then on the Packing tab of the menu bar&#8217;s properties set the position to be zero, so that the menu is at the top of the window.</li>
<li>Then edit the menu so that only the  File, Edit, and Help menu&#8217;s remain.</li>
<li>Add handlers to each of the files menu items: on_file_new, on_file_open, on_file_save, on_file_save_as</li>
</ol>
<p><img style="margin: 0pt 10px 10px 0pt;" src="http://www.learningpython.com/images/WordPy_02/wordpy_02_01.png" alt="GLADE Window PyWine" border="0" /></p>
<h2>The Code</h2>
<p>That&#8217;s it for editing the GUI, now we have to go and edit the code.  The first step is to connect all of the menu events with our code:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-identifier">dic</span><span class="hl-default"> = {</span><span class="hl-quotes">&quot;</span><span class="hl-string">on_wndMain_destroy</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">quit</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnBold_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnBold_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnItalic_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnItalic_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnLink_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnLink_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnBlockQuote_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnBlockQuote_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnDel_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnDel_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnIns_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnIns_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnImage_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnImage_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnUnorderedList_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnUnorderedList_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnOrderedList_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnOrderedList_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnListItem_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnListItem_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnCode_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnCode_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnMore_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnMore_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnSettings_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnSettings_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnpost_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnpost_clicked</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_file_new</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_file_new</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_file_open</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_file_open</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_file_save</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_file_save</span><span class="hl-default">
		, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_file_save_as</span><span class="hl-quotes">&quot;</span><span class="hl-default">: </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_file_save_as</span><span class="hl-default">}
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wTree</span><span class="hl-default">.</span><span class="hl-identifier">signal_autoconnect</span><span class="hl-brackets">(</span><span class="hl-identifier">dic</span><span class="hl-brackets">)</span></pre></div></div>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_file_new</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:

</span><span class="hl-reserved">def </span><span class="hl-identifier">on_file_open</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:

</span><span class="hl-reserved">def </span><span class="hl-identifier">on_file_save</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:

</span><span class="hl-reserved">def </span><span class="hl-identifier">on_file_save_as</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">. </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:</span></pre></div></div>
<p><span id="more-41"></span></p>
<p>Now when we save and load the post we will need to use the same xml tags, so instead of typing them twice (or in case we want to change them) I decided to save them as a dictionary in the WordPy class:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-identifier">MAIN_TAG</span><span class="hl-default"> = </span><span class="hl-number">0
</span><span class="hl-identifier">POST_TAG</span><span class="hl-default"> = </span><span class="hl-number">1
</span><span class="hl-identifier">TITLE_TAG</span><span class="hl-default"> = </span><span class="hl-number">2
</span><span class="hl-identifier">TEXT_TAG</span><span class="hl-default"> = </span><span class="hl-number">3
</span><span class="hl-identifier">SETTINGS_TAG</span><span class="hl-default"> = </span><span class="hl-number">4
</span><span class="hl-identifier">URL_TAG</span><span class="hl-default"> = </span><span class="hl-number">5
</span><span class="hl-identifier">USERNAME_TAG</span><span class="hl-default"> = </span><span class="hl-number">6
</span><span class="hl-identifier">PASSWORD_TAG</span><span class="hl-default"> = </span><span class="hl-number">7

</span><span class="hl-reserved">class </span><span class="hl-identifier">WordPy</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This is the Wordpy application.  It is a simple PyGTK
	application that interacts with the WorPress Python library.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">_xml_tags</span><span class="hl-default"> = {
			</span><span class="hl-identifier">MAIN_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">WordPy</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">POST_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">Post</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">TITLE_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">Title</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">TEXT_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">Text</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">URL_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">URL</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">SETTINGS_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">Settings</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">USERNAME_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">Username</span><span class="hl-quotes">&quot;</span><span class="hl-default">
			, </span><span class="hl-identifier">PASSWORD_TAG</span><span class="hl-default"> : </span><span class="hl-quotes">&quot;</span><span class="hl-string">password</span><span class="hl-quotes">&quot;</span><span class="hl-default">
	}</span></pre></div></div>
<p>Now when we save and load we can get the username xml tag like so:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">USERNAME_TAG</span><span class="hl-brackets">]</span></pre></div></div>
<p>And if someone wants to import WordPy into their own Python project, they could get at the tags (if they didn&#8217;t have a WordPy object instantiated) like so:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">WordPy</span><span class="hl-default">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">USERNAME_TAG</span><span class="hl-brackets">]</span></pre></div></div>
<p>We also need to add a new element in the __init__() function:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-reserved">None</span></pre></div></div>
<p>This will be the full path to the xml file that is represents the current post, it starts off as None, since when we first start WordPy the blank post is not associated with any xml file.</p>
<p>We will also need to do some file browsing for the save, open, and save as events so we&#8217;ll borrow the file_browse() function from the <a href="http://www.learningpython.com/2006/09/02/extending-our-pygtk-application/">Extending our PyGTK application</a> tutorial (to learn more about the function and how it works please read the tutorial):</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment"># Borrowed from the PyWine project
</span><span class="hl-reserved">def </span><span class="hl-identifier">file_browse</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">dialog_action</span><span class="hl-code">, </span><span class="hl-identifier">file_name</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This function is used to browse for a pyWine file.
	It can be either a save or open dialog depending on
	what dialog_action is.
	The path to the file will be returned if the user
	selects one, however a blank string will be returned
	if they cancel or do not select one.
	dialog_action - The open or save mode for the dialog either
	gtk.FILE_CHOOSER_ACTION_OPEN, gtk.FILE_CHOOSER_ACTION_SAVE
	@param file_name - Default name when doing a save
	@returns - File Name, or None on cancel.
	</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">dialog_action</span><span class="hl-code">==</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_OPEN</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">dialog_buttons</span><span class="hl-default"> = </span><span class="hl-brackets">(</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">STOCK_CANCEL</span><span class="hl-code">
			, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">RESPONSE_CANCEL</span><span class="hl-code">
			, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">STOCK_OPEN</span><span class="hl-code">
			, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">RESPONSE_OK</span><span class="hl-brackets">)
		</span><span class="hl-identifier">dlg_title</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Open Post</span><span class="hl-quotes">&quot;
	</span><span class="hl-reserved">else</span><span class="hl-default">:
		</span><span class="hl-identifier">dialog_buttons</span><span class="hl-default"> = </span><span class="hl-brackets">(</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">STOCK_CANCEL</span><span class="hl-code">
			, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">RESPONSE_CANCEL</span><span class="hl-code">
			, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">STOCK_SAVE</span><span class="hl-code">
			, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">RESPONSE_OK</span><span class="hl-brackets">)
		</span><span class="hl-identifier">dlg_title</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Save Post</span><span class="hl-quotes">&quot;

	</span><span class="hl-identifier">file_dialog</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">FileChooserDialog</span><span class="hl-brackets">(</span><span class="hl-identifier">title</span><span class="hl-code">=</span><span class="hl-identifier">dlg_title</span><span class="hl-code">
		, </span><span class="hl-identifier">action</span><span class="hl-code">=</span><span class="hl-identifier">dialog_action</span><span class="hl-code">
		, </span><span class="hl-identifier">buttons</span><span class="hl-code">=</span><span class="hl-identifier">dialog_buttons</span><span class="hl-brackets">)
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">set the filename if we are saving</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">dialog_action</span><span class="hl-code">==</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_SAVE</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">file_dialog</span><span class="hl-default">.</span><span class="hl-identifier">set_current_name</span><span class="hl-brackets">(</span><span class="hl-identifier">file_name</span><span class="hl-brackets">)
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Create and add the pywine filter</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">filter</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">FileFilter</span><span class="hl-brackets">()
	</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">set_name</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">WordPy Post</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">add_pattern</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">*.</span><span class="hl-quotes">&quot;</span><span class="hl-code"> + </span><span class="hl-identifier">FILE_EXT</span><span class="hl-brackets">)
	</span><span class="hl-identifier">file_dialog</span><span class="hl-default">.</span><span class="hl-identifier">add_filter</span><span class="hl-brackets">(</span><span class="hl-identifier">filter</span><span class="hl-brackets">)
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">dialog_action</span><span class="hl-code">==</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_OPEN</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Create and add the 'all files' filter</span><span class="hl-quotes">&quot;&quot;&quot;
		</span><span class="hl-identifier">filter</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">FileFilter</span><span class="hl-brackets">()
		</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">set_name</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">All files</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
		</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">add_pattern</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">*</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
		</span><span class="hl-identifier">file_dialog</span><span class="hl-default">.</span><span class="hl-identifier">add_filter</span><span class="hl-brackets">(</span><span class="hl-identifier">filter</span><span class="hl-brackets">)

	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Init the return value</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">result</span><span class="hl-default"> = </span><span class="hl-reserved">None
	if </span><span class="hl-identifier">file_dialog</span><span class="hl-default">.</span><span class="hl-identifier">run</span><span class="hl-brackets">()</span><span class="hl-default"> == </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">RESPONSE_OK</span><span class="hl-default">:
		</span><span class="hl-identifier">result</span><span class="hl-default"> = </span><span class="hl-identifier">file_dialog</span><span class="hl-default">.</span><span class="hl-identifier">get_filename</span><span class="hl-brackets">()
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">dialog_action</span><span class="hl-code">==</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_SAVE</span><span class="hl-brackets">)</span><span class="hl-default">:
			</span><span class="hl-identifier">result</span><span class="hl-default">, </span><span class="hl-identifier">extension</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">splitext</span><span class="hl-brackets">(</span><span class="hl-identifier">result</span><span class="hl-brackets">)
			</span><span class="hl-identifier">result</span><span class="hl-default"> = </span><span class="hl-identifier">result</span><span class="hl-default"> + </span><span class="hl-quotes">&quot;</span><span class="hl-string">.</span><span class="hl-quotes">&quot;</span><span class="hl-default"> + </span><span class="hl-identifier">FILE_EXT
	file_dialog</span><span class="hl-default">.</span><span class="hl-identifier">destroy</span><span class="hl-brackets">()

	</span><span class="hl-reserved">return </span><span class="hl-identifier">result</span></pre></div></div>
<p>Note that this function is somewhat different then the original in that it returns None if the users cancels the operation rather then returning a blank string.</p>
<p>I set FILE_EXT to &#8220;wpx&#8221;, which stands for WordPy xml, at the beginning of the WordPy.py file near the top:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-identifier">FILE_EXT</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">wpx</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p>Another helper function that I added is the set_post_text function:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">set_post_text</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">text</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Simple Helper function that sets the text
	in the text View.
	@param text - The text that will be put into
	the text view.
	</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-comment">#select all of the text
	</span><span class="hl-identifier">start</span><span class="hl-default">, </span><span class="hl-identifier">end</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_bounds</span><span class="hl-brackets">()
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">select_range</span><span class="hl-brackets">(</span><span class="hl-identifier">end</span><span class="hl-code">,</span><span class="hl-identifier">start</span><span class="hl-brackets">)
	</span><span class="hl-comment">#insert over the selection i.e. replace all the text
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">insert_text</span><span class="hl-brackets">(</span><span class="hl-identifier">text</span><span class="hl-brackets">)
	</span><span class="hl-comment">#put the selection at the end.
	</span><span class="hl-identifier">start</span><span class="hl-default">, </span><span class="hl-identifier">end</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_bounds</span><span class="hl-brackets">()
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">select_range</span><span class="hl-brackets">(</span><span class="hl-identifier">end</span><span class="hl-code">,</span><span class="hl-identifier">end</span><span class="hl-brackets">)</span></pre></div></div>
<p>It&#8217;s a simple helper function that sets the post text.  It does this by selecting all of the text in the gtk.TextView and then calls the insert_text() function (detailed in the  previous tutorial) which will overwrite what is selected in the gtk.TextView (in this case everything) with the text that it is passed.  After that we simply move the cursor caret to the end of the text.</p>
<h3>Saving the post</h3>
<p>Now that we have all of the base code in place we can start work on actually saving our file to xml, to do that we will use the <a href="http://docs.python.org/lib/module-xml.dom.minidom.html">xml.dom.minidom</a> module.  The reason that I decided to use the xml.dom.minidom object as opposed to the xml.dom object is because the:</p>
<blockquote><p>xml.dom.minidom is a light-weight implementation of the Document Object Model interface. It is intended to be simpler than the full DOM and also significantly smaller.</p></blockquote>
<p>This is perfect for us since we for saving and loading we do not need to perform any exceedingly difficult xml tasks.</p>
<p>The first function we are going to implement is the on_file_save() function:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_file_save</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This function saves the current post as an XML file</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-comment"># Let the user browse for the save location and name
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-code"> == </span><span class="hl-reserved">None</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">file_browse</span><span class="hl-brackets">(</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_SAVE</span><span class="hl-brackets">)
	</span><span class="hl-comment">#If we have a xml_file
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_save_to_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">))</span><span class="hl-default">:
			</span><span class="hl-comment">#Allright it all worked! Set the Title
			</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">set_window_title_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>This function is pretty simple since it relies on many other functions, this was done so that a lot of the code could be re-used by the on_file_save_as() function. The first thing we do is check to see if self.xml_name has been set, if it hasn&#8217;t we pop up a save dialog and let the user select the location where their file will be saved.  Then if they chose a filename rather then cancelling we will actually start saving our data to xml.</p>
<p>The two main functions we use to accomplish this are xml_save_to_file() and set_window_title_file().  set_window_title_file() is a very simple function that sets the main windows title based upon a file path:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">set_window_title_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the windows title, take it from xml_file.
	@param xml_file - string - The xml file name that we will
	base the window title off of
	</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">main_window</span><span class="hl-default">.</span><span class="hl-identifier">set_title</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">WordPy - %s</span><span class="hl-quotes">&quot;</span><span class="hl-code">
			% </span><span class="hl-brackets">(</span><span class="hl-identifier">os</span><span class="hl-code">.</span><span class="hl-identifier">path</span><span class="hl-code">.</span><span class="hl-identifier">basename</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)))
	</span><span class="hl-reserved">else</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">main_window</span><span class="hl-default">.</span><span class="hl-identifier">set_title</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">WordPy - Untitled</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>The more complicated function is the xml_save_to_file() function:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">xml_save_to_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Save the current post to xml_file
	@param xml_file - string - path to file that
	we will save the xml to.
	@returns boolean - True success. False failure
	</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-comment">#Init return value
	</span><span class="hl-identifier">success</span><span class="hl-default"> = </span><span class="hl-reserved">False

	</span><span class="hl-comment">#Get the available DOM Implementation
	</span><span class="hl-identifier">impl</span><span class="hl-default"> = </span><span class="hl-identifier">minidom</span><span class="hl-default">.</span><span class="hl-identifier">getDOMImplementation</span><span class="hl-brackets">()
	</span><span class="hl-comment">#Create the document, with wordpy as to base node
	</span><span class="hl-identifier">xml_document</span><span class="hl-default"> = </span><span class="hl-identifier">impl</span><span class="hl-default">.</span><span class="hl-identifier">createDocument</span><span class="hl-brackets">(</span><span class="hl-reserved">None</span><span class="hl-code">, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">MAIN_TAG</span><span class="hl-brackets">]</span><span class="hl-code">, </span><span class="hl-reserved">None</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Save the post settings into the xml
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">xml_save</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Save the Blog settings into the XML
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">BlogSettings</span><span class="hl-default">.</span><span class="hl-identifier">xml_save</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Now actually try to save the file
	</span><span class="hl-reserved">try</span><span class="hl-default">:
		</span><span class="hl-identifier">save_file</span><span class="hl-default"> = </span><span class="hl-builtin">open</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">w</span><span class="hl-quotes">'</span><span class="hl-brackets">)
		</span><span class="hl-comment">#write the xml document to disc
		</span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">documentElement</span><span class="hl-default">.</span><span class="hl-identifier">writexml</span><span class="hl-brackets">(</span><span class="hl-identifier">save_file</span><span class="hl-brackets">)
		</span><span class="hl-identifier">save_file</span><span class="hl-default">.</span><span class="hl-identifier">close</span><span class="hl-brackets">()
	</span><span class="hl-reserved">except IOError</span><span class="hl-default">, </span><span class="hl-brackets">(</span><span class="hl-identifier">errno</span><span class="hl-code">, </span><span class="hl-identifier">strerror</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">show_error_dlg</span><span class="hl-brackets">(
			</span><span class="hl-quotes">&quot;</span><span class="hl-string">Error saving post(%s): %s</span><span class="hl-quotes">&quot;</span><span class="hl-code"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">errno</span><span class="hl-code">, </span><span class="hl-identifier">strerror</span><span class="hl-brackets">))
	</span><span class="hl-reserved">else</span><span class="hl-default">:
		</span><span class="hl-comment">#Allright it all worked! Set the return value
		</span><span class="hl-identifier">success</span><span class="hl-default"> = </span><span class="hl-reserved">True

	return </span><span class="hl-identifier">success</span></pre></div></div>
<p>The code is a bit complicated so I will take a little bit of time trying to explain each part in it.  The first thing that we do (after initializing the return value) is call minidom.GetDomImplementation() to get a suitable DOM implementation.  You can read more about the Document Object Model in the python documentation <a href="http://docs.python.org/lib/module-xml.dom.html">here</a>.  We then use that DOM implementation to create our xml document using self._xml_tags[MAIN_TAG] as the main tag for our xml document.  Basically this creates:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre>&lt;WordPy&gt;&lt;/WordPy&gt;</pre></div></div>
<p>Then we call two functions self.xml_save() and self.BlogSettings.xml_save() which are functions that will actually save our data into the xml document.  Then we try to open our self.xml_file and write the xml document into that file using the writexml function:</p>
<blockquote><p><strong>writexml(  	writer[,indent=""[,addindent=""[,newl=""]]])</strong><br />
Write XML to the writer object. The writer should have a write() method which matches that of the file object interface. The indent parameter is the indentation of the current node. The addindent parameter is the incremental indentation to use for subnodes of the current one. The newl parameter specifies the string to use to terminate newlines.</p></blockquote>
<p>After that we simply set the windows title based on self.xml_file so that the user knows which file they are currently working with.</p>
<p>The next function to look at is the WordPy.xml_save() function which actually looks more complicated then it really is:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">xml_save</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Save the current blog post to an xml document.
	@param xml_document - xml.dom.minidom.Document object -
	The xml document that we will save the post to.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-comment">#First create the &quot;post&quot; xml element
	</span><span class="hl-identifier">post_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">POST_TAG</span><span class="hl-brackets">])  </span><span class="hl-comment"># creates &lt;post&gt;&lt;/post&gt;
	#Title
	</span><span class="hl-identifier">title</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enTitle</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">()
	</span><span class="hl-comment">#Text
	</span><span class="hl-identifier">start</span><span class="hl-default">, </span><span class="hl-identifier">end</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_bounds</span><span class="hl-brackets">()
	</span><span class="hl-identifier">text</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">(</span><span class="hl-identifier">start</span><span class="hl-code">, </span><span class="hl-identifier">end</span><span class="hl-brackets">)
	</span><span class="hl-comment"># creates &lt;title&gt;&lt;/title&gt;
	</span><span class="hl-identifier">title_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">TITLE_TAG</span><span class="hl-brackets">])
	</span><span class="hl-comment">#Create &lt;title&gt;title text&lt;/title&gt;
	</span><span class="hl-identifier">title_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-code">.</span><span class="hl-identifier">createTextNode</span><span class="hl-brackets">(</span><span class="hl-identifier">title</span><span class="hl-brackets">))
	</span><span class="hl-comment"># creates &lt;text&gt;&lt;/text&gt;
	</span><span class="hl-identifier">text_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">TEXT_TAG</span><span class="hl-brackets">])
	</span><span class="hl-comment"># creates &lt;text&gt;text&lt;/text&gt;
	</span><span class="hl-identifier">text_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-code">.</span><span class="hl-identifier">createTextNode</span><span class="hl-brackets">(</span><span class="hl-identifier">text</span><span class="hl-brackets">))
	</span><span class="hl-comment">#Now create &lt;post&gt;&lt;title&gt;title text&lt;/title&gt;&lt;text&gt;text&lt;/text&gt;&lt;/post&gt;
	</span><span class="hl-identifier">post_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">title_element</span><span class="hl-brackets">)
	</span><span class="hl-identifier">post_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">text_element</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Now add to the xml docuemnt
	</span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">documentElement</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">post_element</span><span class="hl-brackets">)</span></pre></div></div>
<p>Basically it&#8217;s quite simple, we call  xml_document.createElement() to create an xml element (see <a href="http://docs.python.org/lib/dom-document-objects.html">this page</a> for more information on functions available to our Document object.)  Then if we want we create a text node (and xml node that contains a text string) using xml_document.createTextNode() and add that to our newly created xml element.</p>
<p>So the first thing we do is create the post element, and then we create the title and text elements and add those to the post element.  Then we add the post element to the root of our xml document using documentElement which always represents the root element of our xml document.  It&#8217;s really quite simple, hopefully the comments in the code will help to explain each basic step.</p>
<p>The other xml_save function we have is the WordPressBlogSettings.xml_save() function which is very similar to the other xml_save() function:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">xml_save</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Save the current blog post to an xml document.
	@param xml_document - xml.dom.minidom.Document object -
	The xml document that we will save the post to.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-comment">#First create the &quot;settings&quot; xml element
	</span><span class="hl-identifier">settings_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">SETTINGS_TAG</span><span class="hl-brackets">])
	</span><span class="hl-comment">#Creates &lt;url&gt;&lt;/url&gt;
	</span><span class="hl-identifier">URL_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">URL_TAG</span><span class="hl-brackets">])
	</span><span class="hl-comment">#Create &lt;url&gt;URL&lt;/url&gt;
	</span><span class="hl-identifier">URL_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-code">.</span><span class="hl-identifier">createTextNode</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">URL</span><span class="hl-brackets">))
	</span><span class="hl-comment">#Creates &lt;username&gt;&lt;/username&gt;
	</span><span class="hl-identifier">username_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">USERNAME_TAG</span><span class="hl-brackets">])
	</span><span class="hl-comment">#Creates &lt;username&gt;Username&lt;/username&gt;
	</span><span class="hl-identifier">username_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-code">.</span><span class="hl-identifier">createTextNode</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">Username</span><span class="hl-brackets">))
	</span><span class="hl-comment">#Creates &lt;password&gt;&lt;/password&gt;
	</span><span class="hl-identifier">password_element</span><span class="hl-default"> = </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">createElement</span><span class="hl-brackets">(</span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">PASSWORD_TAG</span><span class="hl-brackets">])
	</span><span class="hl-comment">#Creates &lt;password&gt;Password&lt;/password&gt;
	</span><span class="hl-identifier">password_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-code">.</span><span class="hl-identifier">createTextNode</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">Password</span><span class="hl-brackets">))
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Now create:
	&lt;post&gt;
		&lt;url&gt;URL&lt;/url&gt;
		&lt;username&gt;Username&lt;/username&gt;
		&lt;password&gt;Password&lt;/password&gt;
	&lt;/post&gt;
	</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">settings_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">URL_element</span><span class="hl-brackets">)
	</span><span class="hl-identifier">settings_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">username_element</span><span class="hl-brackets">)
	</span><span class="hl-identifier">settings_element</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">password_element</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Now add to the xml docuemnt
	</span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">documentElement</span><span class="hl-default">.</span><span class="hl-identifier">appendChild</span><span class="hl-brackets">(</span><span class="hl-identifier">settings_element</span><span class="hl-brackets">)</span></pre></div></div>
<p>After all this is set and done we end up with an xml file that looks similar to this although not spaced as nicely:</p>
<pre>
<div class="hl-surround" ><div class="hl-main"><pre>&lt;wordpy&gt;
	&lt;post&gt;
		&lt;title&gt;My Blog Post&lt;/title&gt;
		&lt;text&gt;Here is my text&lt;/text&gt;
	&lt;/post&gt;
	&lt;settings&gt;
		&lt;url&gt;	http://www.myblog.com/wordpress/xmlrpc.php&lt;/url&gt;
		&lt;username&gt;user&lt;/username&gt;
		&lt;password&gt;password&lt;/password&gt;
	&lt;/settings&gt;
&lt;/wordpy&gt;</pre></div></div>
</pre>
<p>Now that you see how we can save a file in response to the File | Save menu command you can probably imagine how we will respond to the File | Save As command:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_file_save_as</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Let the user save the current file to a new location.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">Untitled</span><span class="hl-quotes">&quot;
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-code"> != </span><span class="hl-reserved">None</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">basename</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)

	</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">file_browse</span><span class="hl-brackets">(</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_SAVE</span><span class="hl-code">, </span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)
	</span><span class="hl-comment">#If we have a xml_file
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_save_to_file</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">))</span><span class="hl-default">:
			</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Allright it all worked! save the current file and
			set the title.</span><span class="hl-quotes">&quot;&quot;&quot;
			</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">xml_file
			self</span><span class="hl-default">.</span><span class="hl-identifier">set_window_title_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>You&#8217;ll notice that it&#8217;s very similar to the on_file_save() function except that we always browse for a file and we pass the name of the current file (if it exists) to the file_browse() function so that the use has a starting point for their save as action.</p>
<p>So that&#8217;s it for saving the next step is opening a saved file.</p>
<h3>Opening an save file</h3>
<p>Opening one of our xml files is very similar to saving them except instead of creating the xml document and each node, we need to loop through an existing document and load each node into our specific variables.  The first thing that we need to do is respond to the File | Open menu command:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_file_open</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:

	</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">file_browse</span><span class="hl-brackets">(</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_OPEN</span><span class="hl-brackets">)
	</span><span class="hl-comment">#If we have a xml_file
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_load_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">))</span><span class="hl-default">:
			</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Allright it all worked! save the current file and
			set the title.</span><span class="hl-quotes">&quot;&quot;&quot;
			</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-identifier">xml_file
			self</span><span class="hl-default">.</span><span class="hl-identifier">set_window_title_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>Pretty standard stuff, we let the user browse for an xml file, and if they don&#8217;t cancel the operation we then load the xml file.  If that is successful we save the path to the xml file and then set the windows title.  Not much happening here as most of the work is done in xml_load_from_file():</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">xml_load_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Load a post from an xml file
	@param xml_file - string - path to file that
	we will load.
	@returns boolean - True success. False failure
	</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-comment">#Init return value
	</span><span class="hl-identifier">success</span><span class="hl-default"> = </span><span class="hl-reserved">False

	</span><span class="hl-comment">#Load the xml_file to a document
	</span><span class="hl-reserved">try</span><span class="hl-default">:
		</span><span class="hl-identifier">xml_document</span><span class="hl-default"> = </span><span class="hl-identifier">minidom</span><span class="hl-default">.</span><span class="hl-identifier">parse</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)</span><span class="hl-default">:
			</span><span class="hl-identifier">success</span><span class="hl-default"> = </span><span class="hl-brackets">((</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_load</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-brackets">))
					</span><span class="hl-identifier">and </span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">BlogSettings</span><span class="hl-code">.</span><span class="hl-identifier">xml_load</span><span class="hl-brackets">(</span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)))
	</span><span class="hl-reserved">except IOError</span><span class="hl-default">, </span><span class="hl-brackets">(</span><span class="hl-identifier">errno</span><span class="hl-code">, </span><span class="hl-identifier">strerror</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">show_error_dlg</span><span class="hl-brackets">(
			</span><span class="hl-quotes">&quot;</span><span class="hl-string">Error loading post file(%s): %s</span><span class="hl-quotes">&quot;</span><span class="hl-code"> % </span><span class="hl-brackets">(</span><span class="hl-identifier">errno</span><span class="hl-code">, </span><span class="hl-identifier">strerror</span><span class="hl-brackets">))
	</span><span class="hl-reserved">except</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">show_error_dlg</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Error loading post file.</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-reserved">return </span><span class="hl-identifier">success</span></pre></div></div>
<p>In this function we create our xml.minidom.Document object by telling the minidom mdule to parse the xml file that was passed to the function.  If that does not succeed we catch the appropriate exceptions and show our error dialog top the user.  If the parsing the file does succeed we load the post and the blog settings from the XML document. WordPy.xml_load() loads the post from the xml document:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">xml_load</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Load the current blog post from an xml document.
	@param xml_document - xml.dom.minidom.Document object -
	The xml document that we will load the post from.
	@returns boolean True - success.  False - Failure.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">title_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">False
	</span><span class="hl-identifier">text_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">False

	</span><span class="hl-comment">#Loop through all child nodes of the root.
	</span><span class="hl-reserved">for </span><span class="hl-identifier">node </span><span class="hl-reserved">in </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">documentElement</span><span class="hl-default">.</span><span class="hl-identifier">childNodes</span><span class="hl-default">:
		</span><span class="hl-comment">#We are looking for the post Node
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">POST_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
			</span><span class="hl-comment"># Now loop through the post nodes children
			</span><span class="hl-reserved">for </span><span class="hl-identifier">item_node </span><span class="hl-reserved">in </span><span class="hl-identifier">node</span><span class="hl-default">.</span><span class="hl-identifier">childNodes</span><span class="hl-default">:
				</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">TITLE_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
					</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the title, the firstChild in this case is
					the actual title text that we saved.</span><span class="hl-quotes">&quot;&quot;&quot;

					</span><span class="hl-comment">#Make sure it's not a blank string
					</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-brackets">)</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enTitle</span><span class="hl-default">.</span><span class="hl-identifier">set_text</span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-code">.</span><span class="hl-identifier">nodeValue</span><span class="hl-brackets">)
					</span><span class="hl-reserved">else</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enTitle</span><span class="hl-default">.</span><span class="hl-identifier">set_text</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-brackets">)
					</span><span class="hl-identifier">title_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">True
				</span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">TEXT_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
					</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the text, the firstChild in this case is
					the actual text that we saved.</span><span class="hl-quotes">&quot;&quot;&quot;
					</span><span class="hl-comment">#Make sure it's not a blank string
					</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-brackets">)</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">set_post_text</span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-code">.</span><span class="hl-identifier">nodeValue</span><span class="hl-brackets">)
					</span><span class="hl-reserved">else</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">set_post_text</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-brackets">)
					</span><span class="hl-identifier">text_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">True
			</span><span class="hl-comment">#Break out of the topmost for loop
			</span><span class="hl-reserved">break

	</span><span class="hl-identifier">return </span><span class="hl-brackets">(</span><span class="hl-identifier">title_loaded </span><span class="hl-reserved">and </span><span class="hl-identifier">text_loaded</span><span class="hl-brackets">)</span></pre></div></div>
<p>Basically what we do when loading our values is loop through the all of the child nodes of the root node looking for nodes that match whatever criteria we are looking for.  So in the xml example file:</p>
<pre>
<div class="hl-surround" ><div class="hl-main"><pre>&lt;wordpy&gt;
	&lt;post&gt;
		&lt;title&gt;My Blog Post&lt;/title&gt;
		&lt;text&gt;Here is my text&lt;/text&gt;
	&lt;/post&gt;
	&lt;settings&gt;
		&lt;url&gt;http://www.myblog.com/wordpress/xmlrpc.php&lt;/url&gt;
		&lt;username&gt;user&lt;/username&gt;
		&lt;password&gt;password&lt;/password&gt;
	&lt;/settings&gt;
&lt;/wordpy&gt;</pre></div></div>
</pre>
<p>The root node or the documentElement item, is the &lt;wordpy&gt; element.  So if we were to loop through its child nodes the first node that we would encounter would be the &lt;post&gt; node and then next node would be the &lt;settings&gt; node.  Then if we looped through he &lt;post&gt; elements children we would encounter the &lt;title&gt; and the &lt;text&gt; node.  The sole child node of either of those two nodes happens to be their actual text.</p>
<p>After explaining that it should be pretty obvious what is happening in the WordPy.xml_load() function.  Basically we loop through all the children of the root node looking for the &lt;post&gt; node.  Once we find it we then loop through all of the  &lt;post&gt; node&#8217;s children looking for the &lt;title&gt; and the &lt;text&gt; node.  When we encounter either the &lt;title&gt; node or the &lt;text&gt; node we get the the nodeValue of the firstChild, if it exists.  The firstChild of either of those two nodes happens to be the actual text node that we want to load.  The nodeValue of the text nodes is their actual text.  If firstChild did not exist it means that a blank string was saved into the text file.</p>
<p>For me the xml metaphoer built up by the xml.dom slightly of falls apart when then actual text is considered another node, but the implementation is simple and works well enough so I shouldn&#8217;t complain. (Plus there is probably a very good reason for this)</p>
<p>We also set boolean values to True to make sure that we know whether or not all of the proper elements were loaded.  This is an optional step as you might not care if everything was loaded properly..</p>
<p>The BlogSettings.xml_load() function does the exact same thing except that it looks for different nodes, as a result I will show it but I won&#8217;t bother explaining it.</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">xml_load</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">xml_document</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Load the current blog post from an xml document.
	@param xml_document - xml.dom.minidom.Document object -
	The xml document that we will load the post from.
	@returns boolean True - success.  False - Failure.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">URL_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">False
	</span><span class="hl-identifier">username_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">False
	</span><span class="hl-identifier">password_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">False

	</span><span class="hl-comment">#Loop through all child nodes of the root.
	</span><span class="hl-reserved">for </span><span class="hl-identifier">node </span><span class="hl-reserved">in </span><span class="hl-identifier">xml_document</span><span class="hl-default">.</span><span class="hl-identifier">documentElement</span><span class="hl-default">.</span><span class="hl-identifier">childNodes</span><span class="hl-default">:
		</span><span class="hl-comment">#We are looking for the post Node
		</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">SETTINGS_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
			</span><span class="hl-comment"># Now loop through the post nodes children
			</span><span class="hl-reserved">for </span><span class="hl-identifier">item_node </span><span class="hl-reserved">in </span><span class="hl-identifier">node</span><span class="hl-default">.</span><span class="hl-identifier">childNodes</span><span class="hl-default">:
				</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">URL_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
					</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the URL</span><span class="hl-quotes">&quot;&quot;&quot;
					</span><span class="hl-comment">#Make sure it's not a blank string
					</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-brackets">)</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">URL</span><span class="hl-default"> = </span><span class="hl-identifier">item_node</span><span class="hl-default">.</span><span class="hl-identifier">firstChild</span><span class="hl-default">.</span><span class="hl-identifier">nodeValue
					</span><span class="hl-reserved">else</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">URL</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;&quot;
					</span><span class="hl-identifier">URL_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">True
				</span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">USERNAME_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
					</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the username</span><span class="hl-quotes">&quot;&quot;&quot;
					</span><span class="hl-comment">#Make sure it's not a blank string
					</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-brackets">)</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">Username</span><span class="hl-default"> = </span><span class="hl-identifier">item_node</span><span class="hl-default">.</span><span class="hl-identifier">firstChild</span><span class="hl-default">.</span><span class="hl-identifier">nodeValue
					</span><span class="hl-reserved">else</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">Username</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;&quot;
					</span><span class="hl-identifier">username_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">True
				</span><span class="hl-identifier">elif </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">nodeName</span><span class="hl-code"> == </span><span class="hl-identifier">WordPy</span><span class="hl-code">.</span><span class="hl-identifier">_xml_tags</span><span class="hl-brackets">[</span><span class="hl-identifier">PASSWORD_TAG</span><span class="hl-brackets">])</span><span class="hl-default">:
					</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set the pasword</span><span class="hl-quotes">&quot;&quot;&quot;
					</span><span class="hl-comment">#Make sure it's not a blank string
					</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">item_node</span><span class="hl-code">.</span><span class="hl-identifier">firstChild</span><span class="hl-brackets">)</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">Password</span><span class="hl-default"> = </span><span class="hl-identifier">item_node</span><span class="hl-default">.</span><span class="hl-identifier">firstChild</span><span class="hl-default">.</span><span class="hl-identifier">nodeValue
					</span><span class="hl-reserved">else</span><span class="hl-default">:
						</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">Password</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;&quot;
					</span><span class="hl-identifier">password_loaded</span><span class="hl-default"> = </span><span class="hl-reserved">True
		</span><span class="hl-comment">#Break out of the topmost for loop
		</span><span class="hl-reserved">break

	</span><span class="hl-identifier">return </span><span class="hl-brackets">(</span><span class="hl-identifier">URL_loaded </span><span class="hl-reserved">and </span><span class="hl-identifier">username_loaded </span><span class="hl-reserved">and </span><span class="hl-identifier">password_loaded</span><span class="hl-brackets">)</span></pre></div></div>
<h3>Starting a new file</h3>
<p>All that&#8217;s left now is to handle the File | New menu command:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_file_new</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enTitle</span><span class="hl-default">.</span><span class="hl-identifier">set_text</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">set_post_text</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">xml_file</span><span class="hl-default"> = </span><span class="hl-reserved">None
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">set_window_title_from_file</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">xml_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>It doesn&#8217;t really do much except blank out the title and text, make it so that there is no xml file, and sets the window title to &#8220;Wordpy Ã¢Â€Â“ Untitled&#8221; (which is what set_window_title will do when passed None as the xml file.)</p>
<p>Since this is a good way to initialize WordPy I call it in the __init__ function:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#initialize to new
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_file_new</span><span class="hl-brackets">(</span><span class="hl-reserved">None</span><span class="hl-brackets">)</span></pre></div></div>
<h2>The End</h2>
<p>You can download the complete code for this tutorial <a href="http://www.learningpython.com/sources/WordPy_0_2.tar.gz">here</a>.</p>
<p>Well that&#8217;s it for this lesson on saving and loading data from an xml file, there are still many more things that need to be done to WordPy, like figuring out what the best way to handle the blog settings are since I&#8217;ve never been happy with the way that they were handled in the previous tutorial.  For example  should they be separate from the post&#8217;s when you save them?  Should there be a list of blog settings?  Should you have to log into your blog first?  I&#8217;m not sure yet but those will be left for another post since this one was simply designed to show one method for saving and loading data from xml files using python.</p>
<p>As always if you have any questions or notice any problems please leave a comment!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2006/10/24/wordpy-02-using-xml-to-save-and-load-data/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>WordPy offline blogging tool</title>
		<link>http://www.learningpython.com/2006/08/19/wordpress-python-library/</link>
		<comments>http://www.learningpython.com/2006/08/19/wordpress-python-library/#comments</comments>
		<pubDate>Sat, 19 Aug 2006 17:31:20 +0000</pubDate>
		<dc:creator>selsine</dc:creator>
				<category><![CDATA[glade]]></category>
		<category><![CDATA[PyGTK]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[WordPy]]></category>

		<guid isPermaLink="false">http://www.learningpython.com/?p=30</guid>
		<description><![CDATA[Topics covered in this tutorial: Glade PyGTK gtk.FileChooserDialog gtk.FileFilter gtk.TextView gtk.TextBuffer gtk.TextMark gtk.MessageDialog You can download the full source for this tutorial here. One of the things that I found the other day while I was surfing the web looking for information on Python was this WordPress Python library. Since I use WordPress for this [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.learningpython.com%2F2006%2F08%2F19%2Fwordpress-python-library%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.learningpython.com%2F2006%2F08%2F19%2Fwordpress-python-library%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Topics covered in this tutorial:</p>
<ul>
<li>Glade</li>
<li>PyGTK</li>
<li>gtk.FileChooserDialog</li>
<li>gtk.FileFilter</li>
<li>gtk.TextView</li>
<li>gtk.TextBuffer</li>
<li>gtk.TextMark</li>
<li>gtk.MessageDialog</li>
</ul>
<p>You can download the full source for this tutorial <a href="http://www.learningpython.com/sources/WordPy_0_1.tar.gz">here</a>.</p>
<p>One of the things that I found the other day while I was surfing the web looking for information on Python was this <a href="http://www.blackbirdblog.it/programmazione/progetti/28#english">WordPress Python library</a>.  Since I use WordPress for this site I thought that I&#8217;d play with it a bit.  The result is this tutorial about using the WordPress library, PyGTK, and Glade.</p>
<p>The first think to do is download the <a href="http://www.blackbirdblog.it/programmazione/progetti/28">library</a>, extract it form the archive, and install it.  Enter the following on the command line in the directory you downloaded the library to in order to install it:</p>
<p><code>python setup.py install</code></p>
<p>Now you have the library installed.  The next step is to create the GUI that we will use to interact with the library.  The GUI will be created using <a href="http://glade.gnome.org/">Glade</a>, if you are new to Glade or PyGTK you might want to read over my two turorials on the subject:  <a href="http://www.learningpython.com/2006/05/07/creating-a-gui-using-pygtk-and-glade/">Creating a GUI using PyGTK and Glade</a> and <a href="http://www.learningpython.com/2006/05/30/building-an-application-with-pygtk-and-glade/">Building an Application with PyGTK and Glade</a>.</p>
<p><span id="more-30"></span></p>
<h2>The GUI</h2>
<p>The first thing that we want to do is create the main GUI, here are the steps for that:</p>
<p><b>Note:</b> These steps are very general if you have trouble following them post a question or read the two initial PyGTK/Glade tutorials in order to become familiar with Glade.</p>
<ol>
<li>Add a window to the project. Set it&#8217;s name to be: &#8216;&#8221;wndMain&#8221; and its title to be: &#8220;WordPy&#8221;.  Set it&#8217;s default height to be 350 and it&#8217;s default width to be 400.</li>
<li>Add a vertical box with five rows</li>
<li>In the first row add horizontal box with two columns, set it&#8217;s &#8220;Expand&#8221; option on the Packing tab to No.  Then add a label that says &#8220;Title:&#8221; in the first column set it&#8217;s width to be 44, and in the second column add a Text Entry.  Call the text entry: &#8220;enTitle&#8221;.  Set the Text Entries padding to be 3.</li>
<li>In the second rod add a horizontal box with 13 items.  make the first item A label, make it&#8217;s &#8220;Text:&#8221;, make it&#8217;s width 44, and make it&#8217;s X Align 0.00.  Then make the next twelve items Buttons.  The buttons will be used to mimic the buttons available when writing a wordpress post:<br />
<blockquote><p>(b)(i)(link)(b-quote)(del)(ins)(img)(ul)(ol)(li)(code)(more)</p></blockquote>
<p>Name each button using the following pattern: btnBold, btnItalic, etc, and add a clicked handler to each button.</li>
<li>In the forth row add a Text View.  On the Widget tab set the Text View&#8217;s (not the Scrolled Window) name to be &#8220;txtPost&#8221; and its wrapping option to be &#8220;Word&#8221;.</li>
<li>Now add another Horizontal Button box to the final row.  Set it&#8217;s layout to be &#8220;End&#8221; and its spacing to be 3.   On the Packing tab set the padding to be 2 and Expand to No.  Set the left-most buttons name to be btnSettings, its label to be &#8220;Settings&#8221;, and it&#8217;s icon to be the &#8220;Properties&#8221; icon.  Set the other buttons name to be btnPost, it&#8217;s label to be &#8220;Post&#8221; and it&#8217;s icon to be the Up icon.</li>
<li>Add a handler for the &#8220;clicked&#8221; signal for each button.  We will use this signal to perform actions when the user clicks on the button.</li>
<li>Add a handler for the wndMain destroy signal (not the destroy_event signal, the destroy signal)</li>
</ol>
<p>That&#8217;s it for the main window, once you have completed all of those steps you should be left with something like this:</p>
<p><img style="margin: 0pt 10px 10px 0pt;" src="http://www.learningpython.com/images/WordPy_01/wordpy_01.png" alt="GLADE Window" border="0" /></p>
<p>Note that I used icons for my buttons instead of using text.  The icons are taken from the latest version of the gnome-icon-theme.</p>
<p>The next GUI element that we are going to create is the Settings dialog that will come up when you press the settings button:</p>
<ol>
<li>Create a new dialog by pressing the dialog button.  Select the Standard Button Layout with Cancel and Ok as your buttons.  Set the dialogs name to be &#8220;dlgSettings&#8221; and its title to be &#8220;Settings&#8221;</li>
<li>Add a new table with three rows and two columns.</li>
<li>In the first row add a Label in the first column and set its label to be &#8220;URL:&#8221;.  In the second column add a Text Entry and set it&#8217;s name to be &#8220;enURL&#8221;.  On the packing tab set the Text Entries H Padding and V padding to both be 2</li>
<li>Replicate step three in row two, except set the Label&#8217;s label to be &#8220;Username&#8221; and the name of the Text Entry to be &#8220;enUsername&#8221;.</li>
<li>Replicate step three in row three, except set the Label&#8217;s label to be &#8220;Password&#8221; and the name of the Text Entry to be &#8220;enPassword&#8221;.  Set the Text Visible option to No, this will display the invisible char instead of the actual text, making this function like a normal password entry.</li>
</ol>
<p>After following those steps you should be left with something that resembles the following:</p>
<p><img style="margin: 0pt 10px 10px 0pt;" src="http://www.learningpython.com/images/WordPy_01/wordpy_02.png" alt="GLADE Window" border="0" /></p>
<p>Finally we need to create the dialog that will be used when the user wants to insert a link into their post:</p>
<ol>
<li>Add another dialog with Ok and Cancel buttons.  Set the dialogs name to be dlgLink and it&#8217;s title to be &#8220;Insert Link&#8221;.</li>
<li>Add a vertical box with two rows, in the first row add a Label, set it&#8217;s label to be: &#8220;Enter the URL&#8221; and it&#8217;s X Allign to be 0.00.  In the second row add an Text Entry and set it&#8217;s name to be enURL.</li>
<li>On the Widget tab of dlgLink dialog&#8217;s properties set the resizable property to No, and on the Common tab set the width to be 300.</li>
</ol>
<p>your dlgLink should look something like this:</p>
<p><img style="margin: 0pt 10px 10px 0pt;" src="http://www.learningpython.com/images/WordPy_01/wordpy_04.png" alt="GLADE Window" border="0" /></p>
<h2>The Code &#8211; Connecting Glade with PyGTK</h2>
<p>Here is the basic code that we use to start up our little WordPy Application and connect it with out glade file (it is the basic code that I used in my <a href="http://www.learningpython.com/2006/05/07/creating-a-gui-using-pygtk-and-glade/">two</a> <a href="http://www.learningpython.com/2006/05/30/building-an-application-with-pygtk-and-glade/#more-25">other</a> tutorials):</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-comment">#!/usr/bin/env python

</span><span class="hl-reserved">import </span><span class="hl-identifier">sys
</span><span class="hl-reserved">try</span><span class="hl-default">:
 	</span><span class="hl-reserved">import </span><span class="hl-identifier">pygtk
  	pygtk</span><span class="hl-default">.</span><span class="hl-identifier">require</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">2.0</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-reserved">except</span><span class="hl-default">:
  	</span><span class="hl-reserved">pass
try</span><span class="hl-default">:
	</span><span class="hl-reserved">import </span><span class="hl-identifier">gtk
  	</span><span class="hl-reserved">import </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">glade
</span><span class="hl-reserved">except</span><span class="hl-default">:
	</span><span class="hl-identifier">sys</span><span class="hl-default">.</span><span class="hl-identifier">exit</span><span class="hl-brackets">(</span><span class="hl-number">1</span><span class="hl-brackets">)

</span><span class="hl-reserved">class </span><span class="hl-identifier">WordPy</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This is the Wordpy application.  It is a simple PyGTK
	application that interacts with the WorPress Python library.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
		
		</span><span class="hl-comment">#Set the Glade file
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">gladefile</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;</span><span class="hl-string">wordpy.glade</span><span class="hl-quotes">&quot;  
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wTree</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">glade</span><span class="hl-default">.</span><span class="hl-identifier">XML</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">gladefile</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">wndMain</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">) 

		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Create our dictionary and connect it, you may notice
		that I have gone with the default function names this time</span><span class="hl-quotes">&quot;&quot;&quot;
		</span><span class="hl-identifier">dic</span><span class="hl-default"> = {</span><span class="hl-quotes">&quot;</span><span class="hl-string">on_wndMain_destroy</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">quit</span><span class="hl-default">
				, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnBold_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnBold_clicked</span><span class="hl-default">
				, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnItalic_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnItalic_clicked</span><span class="hl-default">
				, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnLink_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnLink_clicked</span><span class="hl-default">
				, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnBlockQuote_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnBlockQuote_clicked</span><span class="hl-default">
				, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnDel_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnDel_clicked</span><span class="hl-default">
				, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnIns_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnIns_clicked</span><span class="hl-default">
				, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnImage_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnImage_clicked</span><span class="hl-default">
				, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnUnorderedList_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnUnorderedList_clicked</span><span class="hl-default">
				, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnOrderedList_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnOrderedList_clicked</span><span class="hl-default">
				, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnListItem_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnListItem_clicked</span><span class="hl-default">
				, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnCode_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnCode_clicked</span><span class="hl-default">
				, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnMore_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnMore_clicked</span><span class="hl-default">
				, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnSettings_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnSettings_clicked</span><span class="hl-default">
				, </span><span class="hl-quotes">&quot;</span><span class="hl-string">on_btnpost_clicked</span><span class="hl-quotes">&quot;</span><span class="hl-default"> : </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">on_btnpost_clicked</span><span class="hl-default">}
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wTree</span><span class="hl-default">.</span><span class="hl-identifier">signal_autoconnect</span><span class="hl-brackets">(</span><span class="hl-identifier">dic</span><span class="hl-brackets">)

       </span><span class="hl-reserved">def </span><span class="hl-identifier">quit</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Quit yourself</span><span class="hl-quotes">&quot;&quot;&quot;
		</span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">main_quit</span><span class="hl-brackets">()
		
		</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnBold_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the bold button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnItalic_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the italic button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnLink_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the link button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnBlockQuote_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the Block Quote button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnDel_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the Del button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnIns_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the Ins button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnImage_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the Image button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnUnorderedList_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the Unordered List button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnOrderedList_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the Ordered List button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnListItem_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the List Item button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnMore_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the bold button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;
		
	</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnCode_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the Code button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;
		
	</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnSettings_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the settings button is clicked.  It will
		show the dlgSettings dialog and let the user set the WordPress
		blog settings.</span><span class="hl-quotes">&quot;&quot;&quot;
		
	</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnpost_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the post button is clicked, this will
		post the post to the blog.</span><span class="hl-quotes">&quot;&quot;&quot;

</span><span class="hl-reserved">if </span><span class="hl-identifier">__name__</span><span class="hl-default"> == </span><span class="hl-quotes">&quot;</span><span class="hl-string">__main__</span><span class="hl-quotes">&quot;</span><span class="hl-default">:
	</span><span class="hl-identifier">word</span><span class="hl-default"> = </span><span class="hl-identifier">WordPy</span><span class="hl-brackets">()
	</span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">main</span><span class="hl-brackets">()</span></pre></div></div>
<p>This code simply shows our wndMain and connects all of our signals with internal functions.  The next bit of code that I&#8217;m going to show is a simple holder class to hold our WordPressBlogSettings, the settings will be pickled into and from a file just to make using this easier.  <b>However</b> the file is text readable so if you are concerned about your wordpress password you might not want to use this:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">class </span><span class="hl-identifier">WordPressBlogSettings</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This class holds the necessary wordpress blog settings
	URL - The URL of the blog
	Username - The username posting
	Password - The password for the username
	</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-reserved">def </span><span class="hl-identifier">__init__</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">File</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-code">, </span><span class="hl-identifier">URL</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-code">, </span><span class="hl-identifier">Username</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-code">, </span><span class="hl-identifier">Password</span><span class="hl-code">=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-brackets">)</span><span class="hl-default">:

		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">URL</span><span class="hl-default"> = </span><span class="hl-identifier">URL
		self</span><span class="hl-default">.</span><span class="hl-identifier">Username</span><span class="hl-default"> = </span><span class="hl-identifier">Username
		self</span><span class="hl-default">.</span><span class="hl-identifier">Password</span><span class="hl-default"> = </span><span class="hl-identifier">Password
		if </span><span class="hl-brackets">(</span><span class="hl-identifier">File</span><span class="hl-code"> != </span><span class="hl-quotes">&quot;&quot;</span><span class="hl-brackets">)</span><span class="hl-default">:
			</span><span class="hl-comment"># Load from file
			</span><span class="hl-reserved">try</span><span class="hl-default">:
				</span><span class="hl-identifier">file</span><span class="hl-default"> = </span><span class="hl-builtin">open</span><span class="hl-brackets">(</span><span class="hl-identifier">File</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">rb</span><span class="hl-quotes">'</span><span class="hl-brackets">)
				</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">URL</span><span class="hl-default"> = </span><span class="hl-identifier">cPickle</span><span class="hl-default">.</span><span class="hl-identifier">load</span><span class="hl-brackets">(</span><span class="hl-identifier">file</span><span class="hl-brackets">)
				</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">Username</span><span class="hl-default"> = </span><span class="hl-identifier">cPickle</span><span class="hl-default">.</span><span class="hl-identifier">load</span><span class="hl-brackets">(</span><span class="hl-identifier">file</span><span class="hl-brackets">)
				</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">Password</span><span class="hl-default"> = </span><span class="hl-identifier">cPickle</span><span class="hl-default">.</span><span class="hl-identifier">load</span><span class="hl-brackets">(</span><span class="hl-identifier">file</span><span class="hl-brackets">)
				</span><span class="hl-identifier">file</span><span class="hl-default">.</span><span class="hl-identifier">close</span><span class="hl-brackets">()
			</span><span class="hl-reserved">except</span><span class="hl-default">:
				</span><span class="hl-reserved">return

	def </span><span class="hl-identifier">save</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">File</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">cPickle the information into the file</span><span class="hl-quotes">&quot;&quot;&quot;

		</span><span class="hl-reserved">try</span><span class="hl-default">:
			</span><span class="hl-identifier">save_file</span><span class="hl-default"> = </span><span class="hl-builtin">open</span><span class="hl-brackets">(</span><span class="hl-identifier">File</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">wb</span><span class="hl-quotes">'</span><span class="hl-brackets">)
			</span><span class="hl-identifier">cPickle</span><span class="hl-default">.</span><span class="hl-identifier">dump</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">URL</span><span class="hl-code">, </span><span class="hl-identifier">save_file</span><span class="hl-brackets">)
			</span><span class="hl-identifier">cPickle</span><span class="hl-default">.</span><span class="hl-identifier">dump</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">Username</span><span class="hl-code">, </span><span class="hl-identifier">save_file</span><span class="hl-brackets">)
			</span><span class="hl-identifier">cPickle</span><span class="hl-default">.</span><span class="hl-identifier">dump</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">Password</span><span class="hl-code">, </span><span class="hl-identifier">save_file</span><span class="hl-brackets">)
			</span><span class="hl-identifier">save_file</span><span class="hl-default">.</span><span class="hl-identifier">close</span><span class="hl-brackets">()
		</span><span class="hl-reserved">except</span><span class="hl-default">:
			</span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">Error saving blog settings.</span><span class="hl-quotes">&quot;</span></pre></div></div>
<p>Now that we have that class done, we&#8217;ll add a WordPressBlogSettings member variable to our WordPy class in the __init__ function:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Get the name of the blog data file, sys.path[0] is the 
path where the script is located</span><span class="hl-quotes">&quot;&quot;&quot;
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">dat_file</span><span class="hl-default"> = </span><span class="hl-identifier">os</span><span class="hl-default">.</span><span class="hl-identifier">path</span><span class="hl-default">.</span><span class="hl-identifier">join</span><span class="hl-brackets">(</span><span class="hl-identifier">sys</span><span class="hl-code">.</span><span class="hl-identifier">path</span><span class="hl-brackets">[</span><span class="hl-number">0</span><span class="hl-brackets">]</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">Blog.dat</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">BlogSettings</span><span class="hl-default"> = </span><span class="hl-identifier">WordPressBlogSettings</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">dat_file</span><span class="hl-brackets">)</span></pre></div></div>
<p>Then change the quit function to look like the following:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">quit</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Quit yourself</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">BlogSettings</span><span class="hl-default">.</span><span class="hl-identifier">save</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">dat_file</span><span class="hl-brackets">)
	</span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">main_quit</span><span class="hl-brackets">()</span></pre></div></div>
<h2>The Code &#8211; Settings Dialog</h2>
<p>In my <a href="http://www.learningpython.com/2006/05/30/building-an-application-with-pygtk-and-glade/">Building an Application with PyGTK and Glade</a> example I created a separate class to handle the properties dialog.  In this example I&#8217;m just going to use a member function of the WordPy class:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">show_dlgSettings</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">BlogSettings</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This function will show the BlogSettings dialog
	It will return the result code from running the dlg.
	BlogSettings - An instance of WordPressBlogSettings.  Its
	values will only be updated if the user presses the OK button
	returns - The result from running the dlg</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-comment">#init to cancel
	</span><span class="hl-identifier">result</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">RESPONSE_CANCEL
	
	</span><span class="hl-comment">#load the dialog from the glade file	  
	</span><span class="hl-identifier">wTree</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">glade</span><span class="hl-default">.</span><span class="hl-identifier">XML</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">gladefile</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">dlgSettings</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Get the actual dialog widget
	</span><span class="hl-identifier">dlg</span><span class="hl-default"> = </span><span class="hl-identifier">wTree</span><span class="hl-default">.</span><span class="hl-identifier">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">dlgSettings</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Get all of the Entry Widgets and set their text
	</span><span class="hl-identifier">enURL</span><span class="hl-default"> = </span><span class="hl-identifier">wTree</span><span class="hl-default">.</span><span class="hl-identifier">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">enURL</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">enURL</span><span class="hl-default">.</span><span class="hl-identifier">set_text</span><span class="hl-brackets">(</span><span class="hl-identifier">BlogSettings</span><span class="hl-code">.</span><span class="hl-identifier">URL</span><span class="hl-brackets">)
	</span><span class="hl-identifier">enUsername</span><span class="hl-default"> = </span><span class="hl-identifier">wTree</span><span class="hl-default">.</span><span class="hl-identifier">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">enUsername</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">enUsername</span><span class="hl-default">.</span><span class="hl-identifier">set_text</span><span class="hl-brackets">(</span><span class="hl-identifier">BlogSettings</span><span class="hl-code">.</span><span class="hl-identifier">Username</span><span class="hl-brackets">)
	</span><span class="hl-identifier">enPassword</span><span class="hl-default"> = </span><span class="hl-identifier">wTree</span><span class="hl-default">.</span><span class="hl-identifier">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">enPassword</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">enPassword</span><span class="hl-default">.</span><span class="hl-identifier">set_text</span><span class="hl-brackets">(</span><span class="hl-identifier">BlogSettings</span><span class="hl-code">.</span><span class="hl-identifier">Password</span><span class="hl-brackets">)

	</span><span class="hl-comment">#run the dialog and store the response		
	</span><span class="hl-identifier">result</span><span class="hl-default"> = </span><span class="hl-identifier">dlg</span><span class="hl-default">.</span><span class="hl-identifier">run</span><span class="hl-brackets">()
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">result</span><span class="hl-code">==</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">RESPONSE_OK</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-comment">#get the value of the entry fields
		</span><span class="hl-identifier">BlogSettings</span><span class="hl-default">.</span><span class="hl-identifier">URL</span><span class="hl-default"> = </span><span class="hl-identifier">enURL</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">()
		</span><span class="hl-identifier">BlogSettings</span><span class="hl-default">.</span><span class="hl-identifier">Username</span><span class="hl-default"> = </span><span class="hl-identifier">enUsername</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">()
		</span><span class="hl-identifier">BlogSettings</span><span class="hl-default">.</span><span class="hl-identifier">Password</span><span class="hl-default"> = </span><span class="hl-identifier">enPassword</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">()
		
	</span><span class="hl-comment">#we are done with the dialog, destroy it
	</span><span class="hl-identifier">dlg</span><span class="hl-default">.</span><span class="hl-identifier">destroy</span><span class="hl-brackets">()
	
	</span><span class="hl-comment">#return the result
	</span><span class="hl-reserved">return </span><span class="hl-identifier">result</span></pre></div></div>
<p>Basically this function takes a WordPressBlogSettings object as a parameter and uses those settings to set the default text on the dialog.  The dlgSettings is shown, and if the user clicks the Ok button then the WordPressSettings are updated. </p>
<p>To show the dialog and update the BlogSettings the following code is used:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_btnSettings_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the settings button is clicked.  It will
	show the dlgSettings dialog and let the user set the WordPress
	blog settings.</span><span class="hl-quotes">&quot;&quot;&quot;
	
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">show_dlgSettings</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">BlogSettings</span><span class="hl-brackets">)</span></pre></div></div>
<h2>Error Dialog</h2>
<p>A quick helper function that I wrote for this project was a quick and easy way to show an error dialog:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">show_error_dlg</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">error_string</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This Function is used to show an error dialog when
	an error occurs.
	error_string - The error string that will be displayed
	on the dialog.
	</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">error_dlg</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">MessageDialog</span><span class="hl-brackets">(</span><span class="hl-identifier">type</span><span class="hl-code">=</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">MESSAGE_ERROR</span><span class="hl-code">
				, </span><span class="hl-identifier">message_format</span><span class="hl-code">=</span><span class="hl-identifier">error_string</span><span class="hl-code">
				, </span><span class="hl-identifier">buttons</span><span class="hl-code">=</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">BUTTONS_OK</span><span class="hl-brackets">)
	</span><span class="hl-identifier">error_dlg</span><span class="hl-default">.</span><span class="hl-identifier">run</span><span class="hl-brackets">()
	</span><span class="hl-identifier">error_dlg</span><span class="hl-default">.</span><span class="hl-identifier">destroy</span><span class="hl-brackets">()</span></pre></div></div>
<p>It&#8217;s a simple function that accepts and error string as a parameter and then uses a gtk.MessageDialog to show the error.</p>
<h2>Working with the gtk.TextView</h2>
<p>I found working with the gtk.TextView object to be quite difficult, it uses an approach to Text controls that I really had not encountered before.  Mainly the <a href="http://www.pygtk.org/pygtk2reference/class-gtktextview.html">gtk.TextView</a> <a href="http://www.pygtk.org/pygtk2reference/class-gtktextbuffer.html">gtk.TextBuffer</a> relationship.  For a full understanding of the gtk.TextView/gtk.TextBuffer relationship you might want to read the <a href="http://developer.gnome.org/doc/API/2.0/gtk/TextWidget.html">GTK+ reference guide</a>.  Here is a brief excerpt that may explain how they two are related:</p>
<blockquote><p>
GTK+ has an extremely powerful framework for multiline text editing. The primary objects involved in the process are GtkTextBuffer, which represents the text being edited, and GtkTextView, a widget which can display a GtkTextBuffer. Each buffer can be displayed by any number of views&#8230;</p>
<p>Most text manipulation is accomplished with iterators, represented by a GtkTextIter. An iterator represents a position between two characters in the text buffer. GtkTextIter is a struct designed to be allocated on the stack; it&#8217;s guaranteed to be copiable by value and never contain any heap-allocated data. Iterators are not valid indefinitely; whenever the buffer is modified in a way that affects the number of characters in the buffer, all outstanding iterators become invalid. (Note that deleting 5 characters and then reinserting 5 still invalidates iterators, though you end up with the same number of characters you pass through a state with a different number).</p>
<p>Because of this, iterators can&#8217;t be used to preserve positions across buffer modifications. To preserve a position, the GtkTextMark object is ideal. You can think of a mark as an invisible cursor or insertion point; it floats in the buffer, saving a position. If the text surrounding the mark is deleted, the mark remains in the position the text once occupied; if text is inserted at the mark, the mark ends up either to the left or to the right of the new text, depending on its gravity. The standard text cursor in left-to-right languages is a mark with right gravity, because it stays to the right of inserted text.
</p></blockquote>
<p>So, a gtk.TextBuffer is the actual text, and it can be displayed in more then one gtkTextView objects which decide how the text will look.  <a href="http://www.pygtk.org/pygtk2reference/class-gtktextiter.html">gtk.TextIter</a> objects are used to iterate through the text, but they will not be valid forever since the text might change.  To keep track of a position in the text &#8220;forever&#8221; <a href="http://www.pygtk.org/pygtk2reference/class-gtktextmark.html">gtk.TextMarks</a> must be used.  You can also use tags and things to format text in a gtk.TextView but we won&#8217;t be using them at all in this tutorial.</p>
<p>Because of the complicated relationship between all of these pyGTK objects I decided to write some helper functions to make working with the text easier.</p>
<p>The first thing we needed to do was get the <a href="http://www.pygtk.org/pygtk2reference/class-gtktextview.html">gtk.TextView</a> and <a href="http://www.pygtk.org/pygtk2reference/class-gtktextbuffer.html">gtk.TextBuffers</a> that we will be working with.  In order to do this we add the following code to the __init__ function:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-comment">#Get the text view
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtPost</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wTree</span><span class="hl-default">.</span><span class="hl-identifier">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">txtPost</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
</span><span class="hl-comment">#Get the buffer associated with the text view
</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtPost</span><span class="hl-default">.</span><span class="hl-identifier">get_buffer</span><span class="hl-brackets">()</span></pre></div></div>
<p>Now that we have the gtk.TextView and the gtk.TextBuffer we can start creating the helper functions.  The first function will get the start and end gtk.TextIter objects that represent the selection:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">get_selection_iters</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This function gets the start and end selection
	iters from the text view.  If there is no selection
	the current position of the cursor will be returned.
	Returns - start,end - gtk.TextIter objects</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-comment">#init
	</span><span class="hl-identifier">start</span><span class="hl-default"> = </span><span class="hl-reserved">None
	</span><span class="hl-identifier">end</span><span class="hl-default"> = </span><span class="hl-reserved">None

	</span><span class="hl-comment">#First check to see that the text buffer is valid
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-reserved">not </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">show_error_dlg</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Text buffer not available</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
		</span><span class="hl-reserved">return </span><span class="hl-identifier">start</span><span class="hl-default">,</span><span class="hl-identifier">end

	</span><span class="hl-comment">#Get the selection bounds
	</span><span class="hl-identifier">bounds</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_selection_bounds</span><span class="hl-brackets">()</span><span class="hl-default">;
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">bounds</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-comment">#If there is a selection we are done
		</span><span class="hl-identifier">start</span><span class="hl-default">,</span><span class="hl-identifier">end</span><span class="hl-default"> = </span><span class="hl-identifier">bounds
	</span><span class="hl-reserved">else</span><span class="hl-default">:
		</span><span class="hl-comment">#There is no selection so just get the cursor mark
		</span><span class="hl-identifier">cursor_mark</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_insert</span><span class="hl-brackets">()
		</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Set start and end to be gtk.TextIter objects at the
		position of the cursor mark</span><span class="hl-quotes">&quot;&quot;&quot;
		</span><span class="hl-identifier">start</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_iter_at_mark</span><span class="hl-brackets">(</span><span class="hl-identifier">cursor_mark</span><span class="hl-brackets">)
		</span><span class="hl-identifier">end</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_iter_at_mark</span><span class="hl-brackets">(</span><span class="hl-identifier">cursor_mark</span><span class="hl-brackets">)

	</span><span class="hl-reserved">return </span><span class="hl-identifier">start</span><span class="hl-default">, </span><span class="hl-identifier">end</span></pre></div></div>
<p>The first thing this function does is initialize our returns values (start and end) to None, just so that the caller function can tell whether the function succeeded or not.  The next thing we do is attempt to get the current selection using <a href="http://www.pygtk.org/pygtk2reference/class-gtktextbuffer.html#method-gtktextbuffer--get-selection-bounds">gtk.TextBuffer.get_selection_bounds()</a> function.  If there is no selection then we use the <a href="http://www.pygtk.org/pygtk2reference/class-gtktextbuffer.html#method-gtktextbuffer--get-insert">gtk.TextBuffer.get_insert()</a> function to get the <a href="http://www.pygtk.org/pygtk2reference/class-gtktextmark.html">gtk.TextMark</a> that is at the current position of the cursor.  Then we use that gtk.TextMark to set the start and end gtk.TextIter object and we&#8217;re done.</p>
<p>The next two helper functions make use of the get_selection_iters() function.  The first is used to insert text into the gtk.TextView, and the second is used to wrap the currently selected text in the gtk.TextView with a start tag and an end tag.  First the insert_text() function:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">insert_text</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">text</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This function inserts text into the text buffer
	self.txtBuffer at the current selection.  If text is
	selected it will be overwritten, otherwise it will simply be
	inserted at the cursor position
	text - The text to be inserted in the buffer
	</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">start</span><span class="hl-default">, </span><span class="hl-identifier">end</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">get_selection_iters</span><span class="hl-brackets">()</span><span class="hl-default">;

	</span><span class="hl-identifier">if </span><span class="hl-brackets">((</span><span class="hl-reserved">not </span><span class="hl-identifier">start</span><span class="hl-brackets">)</span><span class="hl-identifier">or</span><span class="hl-brackets">(</span><span class="hl-reserved">not </span><span class="hl-identifier">end</span><span class="hl-brackets">))</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">show_error_dlg</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Error inserting text</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
		</span><span class="hl-reserved">return</span><span class="hl-default">;

	</span><span class="hl-comment">#Delete the selected text (start and end will be equal after)
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">delete</span><span class="hl-brackets">(</span><span class="hl-identifier">start</span><span class="hl-code">,</span><span class="hl-identifier">end</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Save a mark at the start position since after we insert
	#the text start will be invalid
	</span><span class="hl-identifier">start_mark</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">create_mark</span><span class="hl-brackets">(</span><span class="hl-reserved">None</span><span class="hl-code">, </span><span class="hl-identifier">start</span><span class="hl-code">, </span><span class="hl-reserved">True</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Insert, end will be set to the end insert position
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">insert</span><span class="hl-brackets">(</span><span class="hl-identifier">end</span><span class="hl-code">,</span><span class="hl-identifier">text</span><span class="hl-brackets">)
	</span><span class="hl-identifier">start</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_iter_at_mark</span><span class="hl-brackets">(</span><span class="hl-identifier">start_mark</span><span class="hl-brackets">)
	</span><span class="hl-comment">#select the text, use end as the first param so that
	#it will be the cursor position
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">select_range</span><span class="hl-brackets">(</span><span class="hl-identifier">end</span><span class="hl-code">,</span><span class="hl-identifier">start</span><span class="hl-brackets">)
	</span><span class="hl-comment">#delete the start mark
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">delete_mark</span><span class="hl-brackets">(</span><span class="hl-identifier">start_mark</span><span class="hl-brackets">)</span></pre></div></div>
<p>The comments in the code should help explain what is happening in this function, but I will explain it briefly.  First we get the start and end <a href="http://www.pygtk.org/pygtk2reference/class-gtktextiter.html">gtk.TextIter</a> objects representing the current selection.  Then we delete that selection and create a <a href="http://www.pygtk.org/pygtk2reference/class-gtktextmark.html">gtk.TextMark</a> at the start location.  The gtk.TextMark is created with left gravity, which means that when text is inserted at it&#8217;s position it will stay to the left of the text rather then being pushed to the right.</p>
<p>Then we insert the text at the end position, which will insert the text and update the position of the end <a href="http://www.pygtk.org/pygtk2reference/class-gtktextiter.html">gtk.TextIter</a> to point at the end of the inserted text.  Next we get the start <a href="http://www.pygtk.org/pygtk2reference/class-gtktextiter.html">gtk.TextIter</a> based off of our start_mark and select all of the text that we just inserted.  Finally we delete the gtk.TextMark that we created and the function is done.</p>
<p>The next text helper function that we will need is a function to wrap text, it&#8217;s similar to the insert_text() function except this function will wrap any selected text with two tags.  If no text is selected then the two tags will be inserted at the cursors position.</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">wrap_selection</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">start_tag</span><span class="hl-code">, </span><span class="hl-identifier">end_tag</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This fucntion is used to wrap the currently selected
	text in the gtk.TextView with start_tag and end_tag. If
	there is no selection start_tag and end_tag will be
	inserted at the cursor position
	start_tag - The text that will go at the start of the
	selection.
	end_tag - The text that will go at the end of the
	selection.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">start</span><span class="hl-default">, </span><span class="hl-identifier">end</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">get_selection_iters</span><span class="hl-brackets">()</span><span class="hl-default">;
	</span><span class="hl-identifier">if </span><span class="hl-brackets">((</span><span class="hl-reserved">not </span><span class="hl-identifier">start</span><span class="hl-brackets">)</span><span class="hl-identifier">or</span><span class="hl-brackets">(</span><span class="hl-reserved">not </span><span class="hl-identifier">end</span><span class="hl-brackets">))</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">show_error_dlg</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Error inserting text</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
		</span><span class="hl-reserved">return</span><span class="hl-default">;
	</span><span class="hl-comment">#Create a mark at the start and end
	</span><span class="hl-identifier">start_mark</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">create_mark</span><span class="hl-brackets">(</span><span class="hl-reserved">None</span><span class="hl-code">,</span><span class="hl-identifier">start</span><span class="hl-code">, </span><span class="hl-reserved">True</span><span class="hl-brackets">)
	</span><span class="hl-identifier">end_mark</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">create_mark</span><span class="hl-brackets">(</span><span class="hl-reserved">None</span><span class="hl-code">, </span><span class="hl-identifier">end</span><span class="hl-code">, </span><span class="hl-reserved">False</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Insert the start_tag
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">insert</span><span class="hl-brackets">(</span><span class="hl-identifier">start</span><span class="hl-code">, </span><span class="hl-identifier">start_tag</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Get the end iter again
	</span><span class="hl-identifier">end</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_iter_at_mark</span><span class="hl-brackets">(</span><span class="hl-identifier">end_mark</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Insert the end tag
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">insert</span><span class="hl-brackets">(</span><span class="hl-identifier">end</span><span class="hl-code">, </span><span class="hl-identifier">end_tag</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Get the start and end iters
	</span><span class="hl-identifier">start</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_iter_at_mark</span><span class="hl-brackets">(</span><span class="hl-identifier">start_mark</span><span class="hl-brackets">)
	</span><span class="hl-identifier">end</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_iter_at_mark</span><span class="hl-brackets">(</span><span class="hl-identifier">end_mark</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Select the text
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">select_range</span><span class="hl-brackets">(</span><span class="hl-identifier">end</span><span class="hl-code">,</span><span class="hl-identifier">start</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Delete the gtk.TextMark objects
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">delete_mark</span><span class="hl-brackets">(</span><span class="hl-identifier">start_mark</span><span class="hl-brackets">)
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">delete_mark</span><span class="hl-brackets">(</span><span class="hl-identifier">end_mark</span><span class="hl-brackets">)</span></pre></div></div>
<p>If you understood the insert_text() function then you will probably understand the wrap_selection() function as they use very similar techniques.  The first thing is to get the start and end selection gtk.TextIters, then create gtk.TextMark objects at both locations.  We create the gtk.TextMark objects at both locations and with different orientations so that when we insert the text we will still know where the original positions were (relative to the text we inserted) are so that we can select everything once we are done.</p>
<p>Then we insert the start_tag, re-get the end gtk.TextIter (since our original is no longer valid after we inserted the text) and insert the end_tag.  After that we simply re-get both the start and end gtk.TextIter objects and then select all the text in between the start_tag and end_tag inclusively.</p>
<h2>The Code Ã¢Â€Â“ The easy buttons</h2>
<p>After we have the two text helper functions you can see how easy it is to populate most of the on_clicked() handlers for our buttons.  Except for on_btnImage_clicked() and on_btnLink_clicked() here are all of the button clicked handlers.</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_btnBold_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the bold button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wrap_selection</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;b&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-code">,</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;/b&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnItalic_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the italic button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wrap_selection</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;i&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-code">,</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;/i&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnBlockQuote_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the Block Quote button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wrap_selection</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;blockquote&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-code">,</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;/blockquote&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnDel_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the Del button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">today</span><span class="hl-default"> = </span><span class="hl-identifier">datetime</span><span class="hl-default">.</span><span class="hl-identifier">date</span><span class="hl-default">.</span><span class="hl-identifier">today</span><span class="hl-brackets">()
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wrap_selection</span><span class="hl-brackets">(</span><span class="hl-identifier">today</span><span class="hl-code">.</span><span class="hl-identifier">strftime</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;del datetime=</span><span class="hl-special">\&quot;</span><span class="hl-string">%Y%m%d</span><span class="hl-special">\&quot;</span><span class="hl-string">&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">,</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;/del&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnIns_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the Ins button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">today</span><span class="hl-default"> = </span><span class="hl-identifier">datetime</span><span class="hl-default">.</span><span class="hl-identifier">date</span><span class="hl-default">.</span><span class="hl-identifier">today</span><span class="hl-brackets">()
	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wrap_selection</span><span class="hl-brackets">(</span><span class="hl-identifier">today</span><span class="hl-code">.</span><span class="hl-identifier">strftime</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;ins datetime=</span><span class="hl-special">\&quot;</span><span class="hl-string">%Y%m%d</span><span class="hl-special">\&quot;</span><span class="hl-string">&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">,</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;/ins&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnUnorderedList_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the Unordered List button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wrap_selection</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;ul&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-code">,</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;/ul&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnOrderedList_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the Ordered List button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wrap_selection</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;ol&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-code">,</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;/ol&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnListItem_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the List Item button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wrap_selection</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;li&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-code">,</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;/li&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnMore_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the bold button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">insert_text</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;!--more--&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

</span><span class="hl-reserved">def </span><span class="hl-identifier">on_btnCode_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the Code button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wrap_selection</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;code&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-code">,</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;/code&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span></pre></div></div>
<p>Pretty straight forward except for maybe the on_btnIns_clicked() and on_btnDel_clicked() functions which make use of the built-in <a href="http://www.python.org/doc/2.3.5/lib/module-datetime.html">datetime</a> module and the <a href="http://www.python.org/doc/2.3.5/lib/node211.html">strftime</a> function to format the current date in the correct manner (YYYYMMDD).  The following line needs to be added to the start of the code:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre><span class="hl-reserved">import </span><span class="hl-identifier">datetime</span></pre></div></div>
<h2> The Code Ã¢Â€Â“ Link Button, Image button, and gtk.FileChooserDialog</h2>
<p>Now we need to get the on_btnLink_clicked() and the on_btnImage_clicked() functions working.  First off I&#8217;ll show you the on_btnLink_clicked() since it&#8217;s the simplest of the two:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_btnLink_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the link button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-comment">#load the dialog from the glade file
	</span><span class="hl-identifier">wTree</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">glade</span><span class="hl-default">.</span><span class="hl-identifier">XML</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">gladefile</span><span class="hl-code">, </span><span class="hl-quotes">&quot;</span><span class="hl-string">dlgLink</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Get the actual dialog widget
	</span><span class="hl-identifier">dlg</span><span class="hl-default"> = </span><span class="hl-identifier">wTree</span><span class="hl-default">.</span><span class="hl-identifier">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">dlgLink</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">enURL</span><span class="hl-default"> = </span><span class="hl-identifier">wTree</span><span class="hl-default">.</span><span class="hl-identifier">get_widget</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">enURL</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">enURL</span><span class="hl-default">.</span><span class="hl-identifier">set_text</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">HTTP://</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Get the selection not and reselect becuase somethimes
	the dialog will remove the selection</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">start</span><span class="hl-default">, </span><span class="hl-identifier">end</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">get_selection_iters</span><span class="hl-brackets">()

	</span><span class="hl-comment">#run the dialog
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">dlg</span><span class="hl-code">.</span><span class="hl-identifier">run</span><span class="hl-brackets">()</span><span class="hl-code">==</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">RESPONSE_OK</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-comment">#Reset the selection
		</span><span class="hl-identifier">if </span><span class="hl-brackets">((</span><span class="hl-identifier">start</span><span class="hl-brackets">)</span><span class="hl-identifier">and</span><span class="hl-brackets">(</span><span class="hl-identifier">end</span><span class="hl-brackets">))</span><span class="hl-default">:
			</span><span class="hl-comment">#Select the text
			</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">select_range</span><span class="hl-brackets">(</span><span class="hl-identifier">end</span><span class="hl-code">,</span><span class="hl-identifier">start</span><span class="hl-brackets">)

		</span><span class="hl-comment">#Wrap the selection with the value of the entry fields
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">wrap_selection</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;a href=</span><span class="hl-special">\&quot;</span><span class="hl-string">%s</span><span class="hl-special">\&quot;</span><span class="hl-string">&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-code"> % </span><span class="hl-identifier">enURL</span><span class="hl-code">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">()</span><span class="hl-code">,</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;/a&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)

	</span><span class="hl-identifier">dlg</span><span class="hl-default">.</span><span class="hl-identifier">destroy</span><span class="hl-brackets">()</span></pre></div></div>
<p>If you&#8217;ve read my <a href="http://www.learningpython.com/2006/05/30/building-an-application-with-pygtk-and-glade/">Building an Application with python and PyGTK tutorial</a> and made it this far in this tutorial then nothing in this code should be that surprising.  First we get the dlgLink&#8217;s widget tree from the glade file, and then we get the actual dialog widget.</p>
<p>Next we get the URL text entry widget and set it&#8217;s default text to be &#8220;HTTP:\\&#8221;.  After that we get the current selection, the reason that we do this is because sometimes I noticed that showing the dialog caused the selection to be removed from the gtk.TextView.  So the quick and easy way to get around this (since the helper function was already written) was to simply get the selection before the dialog is visible for any length of time, and then reset the selection once the used has exited the dialog.</p>
<p>Then we have to run the dialog and wait to see if the used clicks the Ok or Cancel button.  If they click Cancel nothing happens, we destroy the dialog and the function is over.  If, however, they click Ok we will then reset the selection, and wrap it with the link tags.</p>
<p>The next thing we are going to do is work on letting the user add an image to their blog post.  To do this we will respond to the on_btnImage_clicked function.  The first thing we need to do is let the user browse for an image.  We will use a <a href="http://www.pygtk.org/pygtk2reference/class-gtkfilechooserdialog.html">gtk.FileChooserDialog</a>, for more information on using a gtk.FileChooserDialog see section <a href="http://www.pygtk.org/pygtk2tutorial/sec-FileChoosers.html">16.6 in the PyGTK Tutorial</a>, where much of the following code is taken:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">browse_for_image</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">This function is used to browse for an image.
	The path to the image will be returned if the user
	selects one, however a blank string will be returned
	if they cancel or do not select one.</span><span class="hl-quotes">&quot;&quot;&quot;
	
	</span><span class="hl-identifier">file_open</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">FileChooserDialog</span><span class="hl-brackets">(</span><span class="hl-identifier">title</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">Select Image</span><span class="hl-quotes">&quot;</span><span class="hl-code">
				, </span><span class="hl-identifier">action</span><span class="hl-code">=</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">FILE_CHOOSER_ACTION_OPEN</span><span class="hl-code">
				, </span><span class="hl-identifier">buttons</span><span class="hl-code">=</span><span class="hl-brackets">(</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">STOCK_CANCEL</span><span class="hl-code">
							, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">RESPONSE_CANCEL</span><span class="hl-code">
							, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">STOCK_OPEN</span><span class="hl-code">
							, </span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">RESPONSE_OK</span><span class="hl-brackets">))
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Create and add the Images filter</span><span class="hl-quotes">&quot;&quot;&quot;		
	</span><span class="hl-identifier">filter</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">FileFilter</span><span class="hl-brackets">()
	</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">set_name</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Images</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">add_mime_type</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">image/png</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">add_mime_type</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">image/jpeg</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">add_mime_type</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">image/gif</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">add_pattern</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">*.png</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">add_pattern</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">*.jpg</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">add_pattern</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">*.gif</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">file_open</span><span class="hl-default">.</span><span class="hl-identifier">add_filter</span><span class="hl-brackets">(</span><span class="hl-identifier">filter</span><span class="hl-brackets">)
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Create and add the 'all files' filter</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">filter</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">FileFilter</span><span class="hl-brackets">()
	</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">set_name</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">All files</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">filter</span><span class="hl-default">.</span><span class="hl-identifier">add_pattern</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">*</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
	</span><span class="hl-identifier">file_open</span><span class="hl-default">.</span><span class="hl-identifier">add_filter</span><span class="hl-brackets">(</span><span class="hl-identifier">filter</span><span class="hl-brackets">)
	
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Init the return value</span><span class="hl-quotes">&quot;&quot;&quot;
	</span><span class="hl-identifier">result</span><span class="hl-default"> = </span><span class="hl-quotes">&quot;&quot;
	</span><span class="hl-reserved">if </span><span class="hl-identifier">file_open</span><span class="hl-default">.</span><span class="hl-identifier">run</span><span class="hl-brackets">()</span><span class="hl-default"> == </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">RESPONSE_OK</span><span class="hl-default">:
		</span><span class="hl-identifier">result</span><span class="hl-default"> = </span><span class="hl-identifier">file_open</span><span class="hl-default">.</span><span class="hl-identifier">get_filename</span><span class="hl-brackets">()
	</span><span class="hl-identifier">file_open</span><span class="hl-default">.</span><span class="hl-identifier">destroy</span><span class="hl-brackets">()
	
	</span><span class="hl-reserved">return </span><span class="hl-identifier">result</span></pre></div></div>
<p>The browse_for_image() function will show the following dialog:</p>
<p><img style="margin: 0pt 10px 10px 0pt;" src="http://www.learningpython.com/images/WordPy_01/wordpy_03.png" alt="Python PyGTK gtk.FileChooserDialog" border="0" /></p>
<p>The first thing we do in the function is create our <a href="http://www.pygtk.org/pygtk2reference/class-gtkfilechooserdialog.html#constructor-gtkfilechooserdialog">gtk.FileChooserDialog</a>.  When constructing the gtk.FileChooseDialog we set it&#8217;s title, the fact that it is a File Open dialog, and what buttons it will have (Ok and Cancel).  Then we use two <a href="http://www.pygtk.org/pygtk2reference/class-gtkfilefilter.html">gtk.FileFilter</a>&#8216;s to control what sort of files the user will be allowed to browse for.  The first file filter sets up the common image types that they will be allowed to browse for and the second filter lets them browse for any file type.</p>
<p>Then the gtk.FileChooserDialog is shown and if the user presses the Ok button the full path to the file that they selected is returned, otherwise an empty string (&#8220;&#8221;) is returned. </p>
<p>We will also add another function to our WordPressBlogSettings class:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">create_wordpress_client</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Quick helper routine used to create the wordpress
	client</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-comment"># prepare client object
	</span><span class="hl-reserved">try</span><span class="hl-default">:
		</span><span class="hl-identifier">wp</span><span class="hl-default"> = </span><span class="hl-identifier">wordpresslib</span><span class="hl-default">.</span><span class="hl-identifier">WordPressClient</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">URL</span><span class="hl-code">
							, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">Username</span><span class="hl-code">
							, </span><span class="hl-identifier">self</span><span class="hl-code">.</span><span class="hl-identifier">Password</span><span class="hl-brackets">)
	</span><span class="hl-reserved">except</span><span class="hl-default">:
		</span><span class="hl-comment">#Error creating Client, setting maybe wrong
		</span><span class="hl-reserved">return None

	</span><span class="hl-comment"># select blog id
	</span><span class="hl-identifier">wp</span><span class="hl-default">.</span><span class="hl-identifier">selectBlog</span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-brackets">)

	</span><span class="hl-reserved">return </span><span class="hl-identifier">wp</span></pre></div></div>
<p>This function simply creates the wordpress client that we need when working with the wordpress library.  It&#8217;s important to note that the blog settings must be correct for the client to be created properly.</p>
<p>To include the wordpress library the follow code is added to the top of the program:</p>
<div class="hl-surround" ><div class="hl-main"><pre><span class="hl-reserved">try</span><span class="hl-default">:
	</span><span class="hl-reserved">import </span><span class="hl-identifier">wordpresslib
</span><span class="hl-reserved">except</span><span class="hl-default">:
	</span><span class="hl-reserved">print </span><span class="hl-quotes">&quot;</span><span class="hl-string">wordpresslib required</span><span class="hl-quotes">&quot;
	</span><span class="hl-identifier">sys</span><span class="hl-default">.</span><span class="hl-identifier">exit</span><span class="hl-brackets">(</span><span class="hl-number">1</span><span class="hl-brackets">)</span></pre></div></div>
<p>This will try to import the wordpress library and then exit if the library cannot be found.</p>
<p>Now we have all the pieces we need to create our on_btnImage_clicked() function:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_btnImage_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the Image button is clicked</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-comment">#Try to get the wordpress client
	</span><span class="hl-identifier">wp</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">BlogSettings</span><span class="hl-default">.</span><span class="hl-identifier">create_wordpress_client</span><span class="hl-brackets">()
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">wp</span><span class="hl-code"> == </span><span class="hl-reserved">None</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-comment">#Error creating Client, setting maybe wrong
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">show_error_dlg</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Error creating Worpress client, please check settings.</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
		</span><span class="hl-comment">#Now get out of here
		</span><span class="hl-reserved">return

	</span><span class="hl-comment"># browse for the image
	</span><span class="hl-identifier">image_file</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">browse_for_image</span><span class="hl-brackets">()

	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">image_file</span><span class="hl-code">!=</span><span class="hl-quotes">&quot;&quot;</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-comment">#We have an image file
		</span><span class="hl-reserved">try</span><span class="hl-default">:
			</span><span class="hl-identifier">imageSrc</span><span class="hl-default"> = </span><span class="hl-identifier">wp</span><span class="hl-default">.</span><span class="hl-identifier">newMediaObject</span><span class="hl-brackets">(</span><span class="hl-identifier">image_file</span><span class="hl-brackets">)
			</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">imageSrc</span><span class="hl-brackets">)</span><span class="hl-default">:
				</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">insert_text</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">&lt;img src=</span><span class="hl-special">\&quot;</span><span class="hl-string">%s</span><span class="hl-special">\&quot;</span><span class="hl-string"> /&gt;</span><span class="hl-quotes">&quot;</span><span class="hl-code"> % </span><span class="hl-identifier">imageSrc</span><span class="hl-brackets">)
			</span><span class="hl-reserved">else</span><span class="hl-default">:
				</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">show_error_dlg</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Error uploading image</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
		</span><span class="hl-reserved">except </span><span class="hl-identifier">wordpresslib</span><span class="hl-default">.</span><span class="hl-identifier">WordPressException</span><span class="hl-default">, </span><span class="hl-identifier">wpe</span><span class="hl-default">:
			</span><span class="hl-comment">#wordpress lib error
			</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">show_error_dlg</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Error uploading image %s</span><span class="hl-quotes">&quot;</span><span class="hl-code"> % </span><span class="hl-identifier">wpe </span><span class="hl-brackets">)</span></pre></div></div>
<p>With all the helpers created this function really isn&#8217;t that difficult.  First we try to get the wordpress client, if we cannot we let the user know that their settings are probably incorrect.  If we get the client correctly we then browse for an image file.</p>
<p>If we get an image file returned we attempt to upload it to our blog,  if that succeeds we insert image HTML code, if it fails in any way we inform the user.</p>
<h2>Posting!</h2>
<p>Well we&#8217;re almost done now, all we need to do is upload the post to the blog.  We do this in the on_btnPost_clicked() function:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre><span class="hl-reserved">def </span><span class="hl-identifier">on_btnpost_clicked</span><span class="hl-brackets">(</span><span class="hl-identifier">self</span><span class="hl-code">, </span><span class="hl-identifier">widget</span><span class="hl-brackets">)</span><span class="hl-default">:
	</span><span class="hl-quotes">&quot;&quot;&quot;</span><span class="hl-string">Called when the post button is clicked, this will
	post the post to the blog.</span><span class="hl-quotes">&quot;&quot;&quot;

	</span><span class="hl-comment">#Try to get the wordpress client
	</span><span class="hl-identifier">wp</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">BlogSettings</span><span class="hl-default">.</span><span class="hl-identifier">create_wordpress_client</span><span class="hl-brackets">()
	</span><span class="hl-identifier">if </span><span class="hl-brackets">(</span><span class="hl-identifier">wp</span><span class="hl-code"> == </span><span class="hl-reserved">None</span><span class="hl-brackets">)</span><span class="hl-default">:
		</span><span class="hl-comment">#Error creating Client, setting maybe wrong
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">show_error_dlg</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Error creating Worpress client, please check settings.</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)
		</span><span class="hl-comment">#Now get out of here
		</span><span class="hl-reserved">return

	</span><span class="hl-identifier">post</span><span class="hl-default"> = </span><span class="hl-identifier">wordpresslib</span><span class="hl-default">.</span><span class="hl-identifier">WordPressPost</span><span class="hl-brackets">()
	</span><span class="hl-identifier">post</span><span class="hl-default">.</span><span class="hl-identifier">allowPings</span><span class="hl-default"> = </span><span class="hl-reserved">True
	</span><span class="hl-identifier">post</span><span class="hl-default">.</span><span class="hl-identifier">allowComments</span><span class="hl-default"> = </span><span class="hl-reserved">True
	</span><span class="hl-comment">#Title
	</span><span class="hl-identifier">post</span><span class="hl-default">.</span><span class="hl-identifier">title</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">enTitle</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">()
	</span><span class="hl-comment">#Text
	</span><span class="hl-identifier">start</span><span class="hl-default">, </span><span class="hl-identifier">end</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_bounds</span><span class="hl-brackets">()
	</span><span class="hl-identifier">post</span><span class="hl-default">.</span><span class="hl-identifier">description</span><span class="hl-default"> = </span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">txtBuffer</span><span class="hl-default">.</span><span class="hl-identifier">get_text</span><span class="hl-brackets">(</span><span class="hl-identifier">start</span><span class="hl-code">, </span><span class="hl-identifier">end</span><span class="hl-brackets">)
	</span><span class="hl-comment">#Now post the post!
	</span><span class="hl-reserved">try</span><span class="hl-default">:
			</span><span class="hl-identifier">new_post_id</span><span class="hl-default"> = </span><span class="hl-identifier">wp</span><span class="hl-default">.</span><span class="hl-identifier">newPost</span><span class="hl-brackets">(</span><span class="hl-identifier">post</span><span class="hl-code">, </span><span class="hl-reserved">True</span><span class="hl-brackets">)
			</span><span class="hl-identifier">success_dlg</span><span class="hl-default"> = </span><span class="hl-identifier">gtk</span><span class="hl-default">.</span><span class="hl-identifier">MessageDialog</span><span class="hl-brackets">(</span><span class="hl-identifier">type</span><span class="hl-code">=</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">MESSAGE_INFO</span><span class="hl-code">
				, </span><span class="hl-identifier">message_format</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">Success! Post has been published!</span><span class="hl-quotes">&quot;</span><span class="hl-code">
				, </span><span class="hl-identifier">buttons</span><span class="hl-code">=</span><span class="hl-identifier">gtk</span><span class="hl-code">.</span><span class="hl-identifier">BUTTONS_OK</span><span class="hl-brackets">)
			</span><span class="hl-identifier">success_dlg</span><span class="hl-default">.</span><span class="hl-identifier">run</span><span class="hl-brackets">()
			</span><span class="hl-identifier">success_dlg</span><span class="hl-default">.</span><span class="hl-identifier">destroy</span><span class="hl-brackets">()
	</span><span class="hl-reserved">except</span><span class="hl-default">:
		</span><span class="hl-identifier">self</span><span class="hl-default">.</span><span class="hl-identifier">show_error_dlg</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Error publishing post.</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-default">;</span></pre></div></div>
<p>So we start off by getting the wordpress cleint, and if that works we get the post&#8217;s title and the post&#8217;s text.  Then we attempt to upload the post, if we get an exception then the post has failed and we let the user know using our show_error_dlg() function.  If we do not get an exception then we show the user a success dialog.</p>
<h2>The End</h2>
<p>Well that&#8217;s it for the WordPy tutorial, I hope to improve on WordPy and get it working as an actual application that can be installed and used by users.  If anyone is interested in this please let me know.</p>
<p>You can download the full source for this tutorial <a href="http://www.learningpython.com/sources/WordPy_0_1.tar.gz">here</a>.</p>
<p>Let me know if you find any bugs, this is a longer tutorial so some might have slipped in.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.learningpython.com/2006/08/19/wordpress-python-library/feed/</wfw:commentRss>
		<slash:comments>48</slash:comments>
		</item>
	</channel>
</rss>

