    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: An Introduction to Programming with GTK+ and Glade in ISO C
and ISO C++ - Part 4</title>
        <link>https://members.accu.org/index.php/journals/784</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>


        <h2>Journal Articles</h2>


<div class="xar-mod-head"><span class="xar-mod-title">CVu Journal Vol 17, #1 - Feb 2005 + Programming Topics</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c98/">171</a>
                    (9)
<br />

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c65/">Programming</a>
                    (877)
<br />

                                            <a href="https://members.accu.org/index.php/journals/c98-65/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/journals/c98+65/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;An Introduction to Programming with GTK+ and Glade in ISO C
and ISO C++ - Part 4</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 February 2005 13:16:10 +00:00 or Thu, 03 February 2005 13:16:10 +00:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a>GTK+ and
C++</h2>
</div>
<p>In the previous article, it was shown that Glade and GObject
could make programs much simpler, and hence increase their
long-term maintainability. However, some problems remain:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Much type checking is done at run-time. This might mean errors
only show up when the code is in production use.</p>
</li>
<li>
<p>Although object-oriented, using objects in C is a bit clunky. In
addition, it is very difficult (although not impossible) to derive
new widgets from existing ones using GObject, or override a class
method or signal. Most programmers do not bother, or just use
&quot;compound widgets&quot;, which are just a container containing more
widgets.</p>
</li>
<li>
<p>Signal handlers are not type safe. This could result in
undefined behaviour, or a crash, if a signal handler does not have
a signature compatible with the signal it is connected to.</p>
</li>
<li>
<p>Signal handlers are functions, and there is often a need to
resort to using global variables and casting structures to type
<tt class="type">gpointer</tt> to pass complex information to a
callback though its data argument. If Glade or GObject are used,
this can be avoided, however.</p>
</li>
</ul>
</div>
<p>gtkmm offers solutions to most of these problems. Firstly, all
of the GTK+ objects are available as native C++ classes. The object
accessor functions are now normal C++ <span class=
"emphasis"><em>class methods</em></span>, which prevents some of
the abuse of objects that could be accomplished in C. The advantage
is less typing, and there is no need to manually cast between an
object's types to use the methods for different classes in the
inheritance hierarchy.</p>
<p>The gtkmm classes may be used just like any other C++ class, and
this includes deriving new objects from them through inheritance.
This also enables all the type checking to be performed by the
compiler, which results in more robust code, since object type
checking is not deferred until run-time.</p>
<p>Signal handling is also more reliable. gtkmm uses the <tt class=
"filename">libsigc++</tt> library, which provides a templated
signal/slot mechanism for type-safe signal handling. The slot
objects allow signal handlers with a different signature than the
signal requires to be bound, which gives greater flexibility than
the C signals allow. Perhaps the most notable feature is that
signal handlers may be class methods, which are recommended over
global functions. This results in further encapsulation of
complexity, and allows the signal handlers to access the member
data of their class. Unlike the Qt library, gtkmm does not require
any source preprocessing, allowing plain ISO C++ to be used without
extensions.</p>
<p><tt class="filename">libglademm</tt> is a C++ wrapper around
<tt class="filename">libglade</tt>, and may be used to dynamically
load user interfaces as in the previous section. It provides
similar functionality, the exception being that signals must be
connected manually. This is because the <tt class=
"filename">libsigc++</tt> signals, connecting to the methods of
individual objects, cannot be connected automatically.</p>
<p><tt class="literal">C++/glade/ogcalc</tt>, shown in Figure 1, is
identical to the previous examples, both in appearance and
functionality. However, internally there are some major
differences.</p>
<div class="figure"><a name="d0e67" id="d0e67"></a>
<div class="mediaobject c2"><img src="/var/uploads/journals/resources/leigh-fig1.png"
align="middle" alt="C++/glade/ogcalc in action."></div>
<p class="title c3">Figure 1. <tt class=
"literal">C++/glade/ogcalc</tt> in action.</p>
</div>
<p>Firstly, the <tt class="function">main()</tt> function no longer
knows anything about the user interface. It merely instantiates an
instance of the <tt class="classname">ogcalc</tt> class, similar to
<tt class="literal">C/gobject/ogcalc</tt>.</p>
<p>The <tt class="classname">ogcalc</tt> class is derived from the
<tt class="classname">Gtk::Window</tt> class, and so contains all
of the functionality of a <tt class="classname">Gtk::Window</tt>,
plus its own additional functions and data. <tt class=
"classname">ogcalc</tt> contains methods called <tt class=
"methodname">on_button_clicked_calculate()</tt> and <tt class=
"methodname">on_button_clicked_reset()</tt> These are the
equivalents of the functions <tt class=
"function">on_button_clicked_calculate()</tt> and <tt class=
"function">on_button_clicked_reset()</tt> used in the previous
examples. Because these functions are class methods, they have
access to the class member data, and as a result are somewhat
simpler than previously.</p>
<p>Two versions are provided, one using the basic C++ classes and
methods to construct the interface, the other using <tt class=
"filename">libglademm</tt> to load and construct the interface as
for the previous examples using Glade. Only the latter is discussed
here. There are a great many similarities between the C and C++
versions not using Glade, and the C Gobject version and the C++
Glade version. It is left as an exercise to the reader to compare
and contrast them.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e117" id="d0e117"></a>Code
Listings</h2>
</div>
<pre class="programlisting">
// C++/glade/ogcalc.h
#include &lt;gtkmm.h&gt;
#include &lt;libglademm.h&gt;
class ogcalc : public Gtk::Window {
public:
  ogcalc();
  virtual ~ogcalc();
protected:
  // Calculation signal handler.
  virtual void on_button_clicked_calculate();
  // Reset signal handler.
  virtual void on_button_clicked_reset();
  // The widgets that are manipulated.
  Gtk::SpinButton* pg_entry;
  Gtk::SpinButton* ri_entry;
  Gtk::SpinButton* cf_entry;
  Gtk::Label* og_result;
  Gtk::Label* abv_result;
  Gtk::Button* quit_button;
  Gtk::Button* reset_button;
  Gtk::Button* calculate_button;
  // Glade interface description.
  Glib::RefPtr&lt;Gnome::Glade::Xml&gt; xml_interface;
};
</pre>
<pre class="programlisting">
// C++/glade/ogcalc.cc
#include &lt;iomanip&gt;
#include &lt;sstream&gt;
#include &lt;sigc++/retype_return.h&gt;
#include &quot;ogcalc.h&quot;
ogcalc::ogcalc() {
  // Set the window title.
  set_title(&quot;OG &amp; ABV Calculator&quot;);
  // Don't permit resizing.
  set_resizable(false);
  // Get the Glade UI and add it to this window.
  xml_interface = Gnome::Glade::Xml::create(
                &quot;ogcalc.glade&quot;, &quot;ogcalc_main_vbox&quot;);
  Gtk::VBox *main_vbox;
  xml_interface-&gt;get_widget(&quot;ogcalc_main_vbox&quot;,
                            main_vbox);
  add(*main_vbox);
  // Pull all of the widgets from the Glade interface
  xml_interface-&gt;get_widget(&quot;pg_entry&quot;, pg_entry);
  xml_interface-&gt;get_widget(&quot;ri_entry&quot;, ri_entry);
  xml_interface-&gt;get_widget(&quot;cf_entry&quot;, cf_entry);
  xml_interface-&gt;get_widget(&quot;og_result&quot;,
                            og_result);
  xml_interface-&gt;get_widget(&quot;abv_result&quot;,
                            abv_result);
  xml_interface-&gt;get_widget(&quot;quit_button&quot;,
                            quit_button);

  xml_interface-&gt;get_widget(&quot;reset_button&quot;,
                            reset_button);
  xml_interface-&gt;get_widget(&quot;calculate_button&quot;,
                            calculate_button);
  // Set up signal handers for buttons.
  quit_button-&gt;signal_clicked().connect(
         SigC::slot(*this, &amp;ogcalc::hide));
  reset_button-&gt;signal_clicked().connect(
         SigC::slot(*this,
             &amp;ogcalc::on_button_clicked_reset));
  reset_button-&gt;signal_clicked().connect(
         SigC::slot(*pg_entry,
             &amp;Gtk::Widget::grab_focus));
  calculate_button-&gt;signal_clicked().connect(
         SigC::slot(*this,
             &amp;ogcalc::on_button_clicked_calculate));
  calculate_button-&gt;signal_clicked().connect(
         SigC::slot(*reset_button,
             &amp;Gtk::Widget::grab_focus));
  // Set up signal handlers for numeric entries.
  pg_entry-&gt;signal_activate().connect(
         SigC::slot(*ri_entry,
             &amp;Gtk::Widget::grab_focus));
  ri_entry-&gt;signal_activate().connect(
         SigC::slot(*cf_entry,
             &amp;Gtk::Widget::grab_focus));
  cf_entry-&gt;signal_activate().connect(
         SigC::hide_return(SigC::slot(*this,
             &amp;Gtk::Window::activate_default)));
  // Ensure calculate is the default.  The Glade
  // default was lost since it was not packed in
  // a window when set.
  calculate_button-&gt;grab_default();
}

ogcalc::~ogcalc() {}

void ogcalc::on_button_clicked_calculate() {
  // PG, RI, and CF values.
  double pg = pg_entry-&gt;get_value();
  double ri = ri_entry-&gt;get_value();
  double cf = cf_entry-&gt;get_value();
  // Calculate OG.
  double og = (ri*2.597)  -(pg*1.644) - 34.4165 + cf;
  // Calculate ABV.
  double abv;
  if (og &lt; 60)
    abv = (og - pg) * 0.130;
  else
    abv = (og - pg) * 0.134;
  std::ostringstream output;
  // Use the user's locale for this stream.
  output.imbue(std::locale(&quot;&quot;));
  output &lt;&lt; &quot;&lt;b&gt;&quot; &lt;&lt; std::fixed
         &lt;&lt; std::setprecision(2)
         &lt;&lt; og &lt;&lt; &quot;&lt;/b&gt;&quot;;
  og_result-&gt;set_markup(
               Glib::locale_to_utf8(output.str()));
  output.str(&quot;&quot;);
  output &lt;&lt; &quot;&lt;b&gt;&quot; &lt;&lt; std::fixed
         &lt;&lt; std::setprecision(2)
         &lt;&lt; abv &lt;&lt; &quot;&lt;/b&gt;&quot;;
  abv_result-&gt;set_markup(
               Glib::locale_to_utf8(output.str()));
}

void ogcalc::on_button_clicked_reset() {
  pg_entry-&gt;set_value(0.0);
  ri_entry-&gt;set_value(0.0);
  cf_entry-&gt;set_value(0.0);
  og_result-&gt;set_text(&quot;&quot;);
  abv_result-&gt;set_text(&quot;&quot;);
}
</pre>
<pre class="programlisting">
// C++/glade/ogcalc-main.cc
#include &lt;gtk/gtk.h&gt;
#include &lt;glade/glade.h&gt;
#include &quot;ogcalc.h&quot;

// This main function merely instantiates the ogcalc
// class and displays it.
int main (int argc, char *argv[]) {
  Gtk::Main kit(argc, argv); // Initialise GTK+.
  ogcalc window;   // Create an ogcalc object.
  kit.run(window);
            // Show window; return when it's closed.
  return 0;
}
</pre>
<p>To build the source, do the following:</p>
<pre class="screen">
cd C++/glade
c++ 'pkg-config -cflags libglademm-2.0' -c ogcalc.cc
c++ 'pkg-config -cflags libglademm-2.0'
                                   -c ogcalc-main.cc
c++ 'pkg-config -libs libglademm-2.0' -o ogcalc
                              ogcalc.o ogcalc-main.o
</pre>
<p>Similarly, for the plain C++ version, which is not discussed in
the tutorial:</p>
<pre class="screen">
cd C++/plain
c++ 'pkg-config -cflags gtkmm-2.0' -c ogcalc.cc
c++ 'pkg-config -cflags gtkmm-2.0' -c ogcalc-main.cc
c++ 'pkg-config -libs gtkmm-2.0' -o ogcalc ogcalc.o
                              ogcalc-main.o
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e134" id="d0e134"></a>Analysis</h2>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e137" id="d0e137"></a>ogcalc.h</h3>
</div>
<p>The header file declares the <tt class="classname">ogcalc</tt>
class.</p>
<pre class="programlisting">
class ogcalc : public Gtk::Window
</pre>
<p>ogcalc is derived from Gtk::Window</p>
<pre class="programlisting">
virtual void on_button_clicked_calculate();
virtual void on_button_clicked_reset();
</pre>
<p><tt class="methodname">on_button_clicked_calculate()</tt> and
<tt class="methodname">on_button_clicked_reset()</tt> are the
signal handling functions, as previously. However, they are now
class member functions, taking no arguments.</p>
<pre class="programlisting">
Gtk::SpinButton* pg_entry;
Glib::RefPtr&lt;Gnome::Glade::Xml&gt; xml_interface;
</pre>
<p>The class data members include pointers to the objects needed by
the callbacks (which can access the class members like normal class
member functions). Note that <tt class=
"classname">Gtk::SpinButton</tt> is a native C++ class. It also
includes a pointer to the XML interface description. <tt class=
"classname">Glib::RefPtr</tt> is a templated, reference-counted,
&quot;smart pointer&quot; class, which will take care of destroying the
pointed-to object when ogcalc is destroyed.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e168" id="d0e168"></a>ogcalc.cc</h3>
</div>
<p>The constructor <tt class="methodname">ogcalc::ogcalc()</tt>
takes care of creating the interface when the class is
instantiated.</p>
<pre class="programlisting">
set_title(&quot;OG &amp; ABV Calculator&quot;);
set_resizable(false);
</pre>
<p>The above code uses member functions of the <tt class=
"classname">Gtk::Window</tt> class. The global functions <tt class=
"function">gtk_window_set_title()</tt> and <tt class=
"function">gtk_window_set_resizable()</tt> were used
previously.</p>
<pre class="programlisting">
xml_interface = Gnome::Glade::Xml::create(
                &quot;ogcalc.glade&quot;, &quot;ogcalc_main_vbox&quot;);
Gtk::VBox *main_vbox;
xml_interface-&gt;get_widget(&quot;ogcalc_main_vbox&quot;,
                          main_vbox);
add(*main_vbox);
</pre>
<p>The Glade interface is loaded using Gnome::Glade::Xml::create(),
in a similar manner to the GObject example, and then the main VBox
is added to the ogcalc object.</p>
<pre class="programlisting">
xml_interface-&gt;get_widget(&quot;pg_entry&quot;, pg_entry);
</pre>
<p>Individual widgets may be obtained from the widget tree using
the static member function <tt class=
"methodname">Gnome::Glade::Xml::get_widget()</tt>.</p>
<p>Because gtkmm uses libsigc++ for signal handling, which uses
class member functions as signal handlers (normal functions may
also be used, too), the signals cannot be connected automatically,
as in the previous example.</p>
<pre class="programlisting">
quit_button-&gt;signal_clicked().connect(
                SigC::slot(*this, &amp;ogcalc::hide));
</pre>
<p>This complex-looking code can be broken into several parts.</p>
<pre class="programlisting">
SigC::slot(*this, &amp;ogcalc::hide)
</pre>
<p>creates a SigC::slot (function object) which points to the
ogcalc::hide() member function of this object.</p>
<pre class="programlisting">
quit_button-&gt;signal_clicked()
</pre>
<p>returns a <tt class="classname">Glib::SignalProxy0</tt> object
(a signal taking no arguments). The <tt class=
"methodname">connect()</tt> method of the signal proxy is used to
connect <tt class="methodname">ogcalc::hide()</tt> to the &quot;clicked&quot;
signal of the <tt class="classname">Gtk::Button</tt>.</p>
<pre class="programlisting">
calculate_button-&gt;signal_clicked().connect(
         SigC::slot(*this,
             &amp;ogcalc::on_button_clicked_calculate));
calculate_button-&gt;signal_clicked().connect(
         SigC::slot(*reset_button,
             &amp;Gtk::Widget::grab_focus));
</pre>
<p>Here two signal handlers are connected to the same signal. When
the &quot;Calculate&quot; button is clicked, <tt class=
"methodname">ogcalc::on_button_clicked_calculate()</tt> is called
first, followed by</p>
<pre class="programlisting">
Gtk::Widget::grab_focus(). 
cf_entry-&gt;signal_activate().connect(
         SigC::hide_return(SigC::slot(*this,
             &amp;Gtk::Window::activate_default)));
</pre>
<p><tt class="methodname">SigC::hide_return</tt> is a special
<tt class="methodname">SigC::slot</tt> used to mask the boolean
value returned by <tt class="methodname">activate_default()</tt>.
The slot created is incompatible with with the slot type required
by the signal, and this &quot;glues&quot; them together.</p>
<p>In the <tt class=
"methodname">ogcalc::on_button_clicked_calculate()</tt> member
function,</p>
<pre class="programlisting">
double pg = pg_entry-&gt;get_value();
</pre>
<p>the member function <tt class=
"methodname">Gtk::SpinButton::get_value()</tt> was previously used
as <tt class="function">gtk_spin_button_get_value()</tt>.</p>
<pre class="programlisting">
std::ostringstream output;
output.imbue(std::locale(&quot;&quot;));
output &lt;&lt; &quot;&lt;b&gt;&quot; &lt;&lt; std::fixed
       &lt;&lt; std::setprecision(2)
       &lt;&lt; og &lt;&lt; &quot;&lt;/b&gt;&quot;;
og_result-&gt;set_markup(
               Glib::locale_to_utf8(output.str()));
</pre>
<p>This code sets the result field text, using an output <tt class=
"classname">stringstream</tt> and Pango markup.</p>
<p>In the <tt class=
"methodname">ogcalc::on_button_clicked_reset()</tt> member
function,</p>
<pre class="programlisting">
pg_entry-&gt;set_value(0.0);
og_result-&gt;set_text(&quot;&quot;);
pg_entry-&gt;grab_focus();
</pre>
<p>class member functions are used to reset and clear the widgets
as in previous examples.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e276" id=
"d0e276"></a>ogcalc-main.cc</h3>
</div>
<p>This file contains a very simple <tt class=
"function">main()</tt> function.</p>
<pre class="programlisting">
Gtk::Main kit(argc, argv); // Initialise GTK+.
ogcalc window;
kit.run(window);
</pre>
<p>A <tt class="classname">Gtk::Main</tt> object is created, and
then an <tt class="classname">ogcalc</tt> class, window, is
instantiated. Finally, the interface is run, using <tt class=
"methodname">kit.run()</tt>. This function will return when window
is hidden, and then the program will exit.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e297" id=
"d0e297"></a>Conclusion</h2>
</div>
<p>Which method of programming one chooses is dependent on many
different factors, such as:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>The languages one is familiar with.</p>
</li>
<li>
<p>The size and nature of the program to be written.</p>
</li>
<li>
<p>The need for long-term maintainability.</p>
</li>
<li>
<p>The need for code reuse.</p>
</li>
</ul>
</div>
<p>For simple programs, such as <tt class=
"literal">C/plain/ogcalc</tt>, there is no problem with writing in
plain C, but as programs become more complex, Glade can greatly
ease the effort needed to develop and maintain the code. The code
reduction and de-uglification achieved through conversion to
<tt class="literal">Glade/libglade</tt> is beneficial even for
small programs, however, so I would recommend that Glade be used
for all but the most trivial code.</p>
<p>The C++ code using gtkmm is slightly more complex than the code
using Glade. However, the benefits of type and signal safety,
encapsulation of complexity and the ability to re-use code through
the derivation of new widgets make gtkmm and <tt class=
"filename">libglademm</tt> an even better choice. Although it is
possible to write perfectly good code in C, gtkmm gives the
programmer security through compiler type checking that plain GTK+
cannot offer. In addition, improved code organisation is possible,
because inheritance allows encapsulation.</p>
<p>GObject provides similar facilities to C++ in terms of providing
classes, objects, inheritance, constructors and destructors etc.,
and is certainly very capable (it is, after all, the basis of the
whole of GTK+!). The code using GObject is very similar to the
corresponding C++ code in terms of its structure. However, C++
still provides facilities such as RAII (Resource Acquisition is
Initialisation) and automatic destruction when an object goes out
of scope that C cannot provide.</p>
<p>There is no &quot;best solution&quot; for everyone. Choose based on your
own preferences and capabilities. In addition, Glade is not the
solution for every problem. The author typically uses a mixture of
custom widgets and Glade interfaces (and your custom widgets can
contain Glade interfaces!). Really dynamic interfaces must be coded
by hand, since Glade interfaces are not sufficiently flexible. Use
what is best for each situation.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e332" id="d0e332"></a>Further
Reading</h2>
</div>
<p>The GTK+ Tutorial, and the GTK+ documentation are highly
recommended. These are available from <a href="http://www.gtk.org/"
target="_top">http://www.gtk.org/</a> The gtkmm documentation is
available from <a href="http://www.gtkmm.org" target=
"_top">http://www.gtkmm.org</a> Unfortunately, some parts of these
manuals are as yet incomplete. I hope that they will be fully
documented in the future, since without good documentation, it will
not be possible to write programs that take advantage of all the
capabilities of GTK+ and gtkmm, without having to read the original
source code. While there is nothing wrong with reading the source,
having good documentation is essential for widespread adoption of
GTK+.</p>
<p>Documentation and examples of GObject are scarce, but Mathieu
Lacage has written an excellent tutorial which is available from
<a href="http://le-hacker.org/papers/gobject/" target=
"_top">http://le-hacker.org/papers/gobject/</a></p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
