<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-10312676</id><updated>2011-04-21T20:49:22.635-07:00</updated><title type='text'>/home/ofey</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ofey.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ofey.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ofey</name><uri>http://www.blogger.com/profile/01522735009406306313</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>14</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-10312676.post-114280875076888811</id><published>2006-03-19T14:36:00.000-08:00</published><updated>2006-03-19T14:52:30.780-08:00</updated><title type='text'>Encounters with LISP</title><content type='html'>Ever since I read &lt;a href="http://www.catb.org/%7Eesr/writings/cathedral-bazaar/"&gt;The Cathedral and the Bazaar &lt;/a&gt;, I've wanted to try out some Lisp. &lt;blockquote&gt;LISP is worth learning for a different reason — the profound enlightenment experience you will have when you finally get it. That experience will make you a better programmer for the rest of your days, even if you never actually use LISP itself a lot. -- Eric S. Raymond&lt;br /&gt;&lt;/blockquote&gt; &lt;blockquote&gt;&lt;/blockquote&gt;But the trouble with most LISP tutorials out there is that they just don't make it easy to get into the flow of this language. Not anymore for me; I found the best LISP book available online.Common Lisp:&lt;a href="http://www.cs.cmu.edu/%7Edst/LispBook/index.html"&gt; A Gentle Introduction to Symbolic Computation&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So far I've just browsed through the book without writing much code. The favourite chapter so far has been &lt;span style="font-style: italic;"&gt;Chapter 7: Applicative Programming&lt;/span&gt;. I can say I finally get it, what &lt;span style="font-weight: bold;"&gt;map &lt;/span&gt;and &lt;span style="font-weight: bold;"&gt;reduce &lt;/span&gt;are all about. The curiosity that's been bothering me ever since that Google paper (&lt;a href="http://labs.google.com/papers/mapreduce-osdi04.pdf"&gt;MapReduce:Simplified Data Processing on Large Clusters&lt;/a&gt; (PDF Alert!!))&lt;br /&gt;&lt;br /&gt;Well, I've used &lt;span style="font-weight: bold;"&gt;map &lt;/span&gt;quite a bit in Perl. But never got to use &lt;span style="font-weight: bold;"&gt;reduce&lt;/span&gt;.  Looks like &lt;a href="http://search.cpan.org/%7Egbarr/Scalar-List-Utils-1.18/lib/List/Util.pm"&gt;List::Util&lt;/a&gt; module is the best way to try it out.&lt;br /&gt;&lt;br /&gt;I don't think I'll ever write much in LISP. But just reading LISP code so far has been fun and educational.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10312676-114280875076888811?l=ofey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ofey.blogspot.com/feeds/114280875076888811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10312676&amp;postID=114280875076888811' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/114280875076888811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/114280875076888811'/><link rel='alternate' type='text/html' href='http://ofey.blogspot.com/2006/03/encounters-with-lisp.html' title='Encounters with LISP'/><author><name>Ofey</name><uri>http://www.blogger.com/profile/01522735009406306313</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10312676.post-114221170385812919</id><published>2006-03-12T16:59:00.000-08:00</published><updated>2006-03-12T17:57:06.646-08:00</updated><title type='text'>Mini Languages and Perl 5</title><content type='html'>I must've been really sleeping under a rock. It took too long but finally encountered &lt;a href="http://www.perl.com/pub/a/2001/06/13/recdecent.html"&gt;Parse::RecDescent&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Feels one step closer to trying out my own mini-language.&lt;br /&gt;&lt;br /&gt;And things should get easier in Perl 6 because &lt;a href="http://www-128.ibm.com/developerworks/library/l-cpregex.html"&gt;grammars are default&lt;/a&gt; in there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10312676-114221170385812919?l=ofey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ofey.blogspot.com/feeds/114221170385812919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10312676&amp;postID=114221170385812919' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/114221170385812919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/114221170385812919'/><link rel='alternate' type='text/html' href='http://ofey.blogspot.com/2006/03/mini-languages-and-perl-5.html' title='Mini Languages and Perl 5'/><author><name>Ofey</name><uri>http://www.blogger.com/profile/01522735009406306313</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10312676.post-112785298873375629</id><published>2005-09-27T13:22:00.000-07:00</published><updated>2005-09-27T13:32:01.193-07:00</updated><title type='text'>Gtk2::Ex::DBITableFilter</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/1906/792/1600/Shot-11.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/1906/792/320/Shot-11.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The buttons and the progressbar come standard with the widget. The progressbar updates during record-fetching.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/1906/792/1600/Shot-2.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/1906/792/320/Shot-2.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Note the excel-like drop down filter boxes in the second image.&lt;br /&gt;&lt;br /&gt;If you want to know more about it, then go to &lt;a href="http://search.cpan.org/%7Eofeyaikon/Gtk2-Ex-DBITableFilter/"&gt;http://search.cpan.org/~ofeyaikon/Gtk2-Ex-DBITableFilter/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10312676-112785298873375629?l=ofey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ofey.blogspot.com/feeds/112785298873375629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10312676&amp;postID=112785298873375629' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/112785298873375629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/112785298873375629'/><link rel='alternate' type='text/html' href='http://ofey.blogspot.com/2005/09/gtk2exdbitablefilter.html' title='Gtk2::Ex::DBITableFilter'/><author><name>Ofey</name><uri>http://www.blogger.com/profile/01522735009406306313</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10312676.post-111820933322497815</id><published>2005-06-07T22:42:00.000-07:00</published><updated>2005-06-07T22:50:35.490-07:00</updated><title type='text'></title><content type='html'>&lt;a href="http://photos1.blogger.com/img/94/3118/640/gtk2-perl-source-1.061.jpg"&gt;&lt;img style="border: 1px solid rgb(0, 0, 0); margin: 2px;" src="http://photos1.blogger.com/img/94/3118/320/gtk2-perl-source-1.061.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;gtk2-perl-source-1.061&lt;br /&gt;&lt;br /&gt;This nice looking picture is a treemap of the Gtk2-Perl source (1.061 version). This treemap was generated using my brand-new Gtk2::Ex::TreeMap module (Find the latest version &lt;a href="http://search.cpan.org/%7Eofeyaikon/"&gt;here&lt;/a&gt;.)&lt;br /&gt;&lt;br /&gt;If you want to know more about treemaps, &lt;a href="http://www.cs.umd.edu/hcil/treemap/"&gt;try&lt;/a&gt; &lt;a href="http://www.marumushi.com/apps/newsmap/newsmap.cfm"&gt;one&lt;/a&gt; &lt;a href="http://codecubed.com/map.html"&gt;of&lt;/a&gt; &lt;a href="http://www.smartmoney.com/marketmap/"&gt;the&lt;/a&gt; following sites.&lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;http://www.cs.umd.edu/hcil/treemap/&lt;br /&gt;http://www.marumushi.com/apps/newsmap/newsmap.cfm&lt;br /&gt;http://codecubed.com/map.html the del.icio.us most popular treemap&lt;br /&gt;http://www.smartmoney.com/marketmap/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10312676-111820933322497815?l=ofey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ofey.blogspot.com/feeds/111820933322497815/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10312676&amp;postID=111820933322497815' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/111820933322497815'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/111820933322497815'/><link rel='alternate' type='text/html' href='http://ofey.blogspot.com/2005/06/gtk2-perl-source-1.html' title=''/><author><name>Ofey</name><uri>http://www.blogger.com/profile/01522735009406306313</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10312676.post-111345767645187329</id><published>2005-04-13T22:47:00.000-07:00</published><updated>2005-04-13T22:50:26.426-07:00</updated><title type='text'>Gtk2::Ex::ICal::Recur</title><content type='html'>&lt;a href='http://photos1.blogger.com/img/94/3118/640/Screenshot.jpg'&gt;&lt;img border='0' style='border:1px solid #000000; margin:2px' src='http://photos1.blogger.com/img/94/3118/320/Screenshot.jpg'&gt;&lt;/a&gt;&lt;br /&gt;Gtk2-Ex-ICal-Recur&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10312676-111345767645187329?l=ofey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ofey.blogspot.com/feeds/111345767645187329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10312676&amp;postID=111345767645187329' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/111345767645187329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/111345767645187329'/><link rel='alternate' type='text/html' href='http://ofey.blogspot.com/2005/04/gtk2exicalrecur_13.html' title='Gtk2::Ex::ICal::Recur'/><author><name>Ofey</name><uri>http://www.blogger.com/profile/01522735009406306313</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10312676.post-110936672256038080</id><published>2005-02-25T13:24:00.000-08:00</published><updated>2005-03-01T21:30:40.220-08:00</updated><title type='text'>Gtk2::Ex::RecordsFilter</title><content type='html'>&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Gtk2::Ex::RecordsFilter &lt;/span&gt;&lt;/span&gt;- A high level widget to browse reasonably large amounts of relational data and select a subset of records. This widget is inspired by the song browser of iTunes.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;span style="font-size:100%;"&gt;&lt;a name="synopsis"&gt;SYNOPSIS&lt;/a&gt;&lt;/span&gt;   &lt;pre&gt;use Gtk2 -init;&lt;br /&gt;use Gtk2::Ex::RecordsFilter;&lt;/pre&gt;  &lt;pre&gt;# Create a recordset&lt;br /&gt;my $recordset = [&lt;br /&gt;[Automobiles,Cars,Toyota,Camry],&lt;br /&gt;[Automobiles,SUV,BMW,Xi],&lt;br /&gt;[Automobiles,SUV,Toyota,Highlander],&lt;br /&gt;[Automobiles,Cars,Mitsubishi,Lancer]&lt;br /&gt;];&lt;/pre&gt;  &lt;pre&gt;# Create the recordsfilter object&lt;br /&gt;my $recordsfilter = Gtk2::Ex::RecordsFilter-&gt;new;&lt;br /&gt;&lt;br /&gt;# Specify the headers for the columns&lt;br /&gt;my $headers = ['Category', 'Sub-Category', 'Brand', 'Model'];&lt;br /&gt;Gtk2::Ex::RecordsFilter-&gt;set_headers($headers);&lt;/pre&gt;  &lt;pre&gt;# Inject data into the widget&lt;br /&gt;Gtk2::Ex::RecordsFilter-&gt;set_data($recordset);&lt;/pre&gt;  &lt;pre&gt;# Get a ref to its widget&lt;br /&gt;my $recordsfilter_widget = $recordsfilter-&gt;get_widget();&lt;/pre&gt;  &lt;pre&gt;# Create the root window&lt;br /&gt;my $window = Gtk2::Window-&gt;new;&lt;br /&gt;$window-&gt;signal_connect(destroy =&gt; sub { Gtk2-&gt;main_quit; });&lt;br /&gt;$window-&gt;set_default_size(500, 300);&lt;/pre&gt;  &lt;pre&gt;# Add the widget to the root window&lt;br /&gt;$window-&gt;add($recordsfilter_widget);&lt;br /&gt;$window-&gt;show_all;&lt;/pre&gt;  &lt;pre&gt;Gtk2-&gt;main;&lt;/pre&gt;  &lt;p&gt; &lt;/p&gt;  &lt;hr /&gt;&lt;span style="font-weight: bold;"&gt;DESCRIPTION&lt;/span&gt;&lt;br /&gt;&lt;p&gt;When working with large amounts of relational records (csv files, database records, music files index), a common task is to filter out a subset or records from a given set. For example, in a &lt;em&gt;master-detail&lt;/em&gt; database design, the &lt;em&gt;master&lt;/em&gt; recordset, which is typically smaller than the &lt;em&gt;detail&lt;/em&gt; recordset, can be filtered out and the filtered subset of &lt;em&gt;master&lt;/em&gt; records can then be used to perform additional tasks on the &lt;em&gt;detail&lt;/em&gt; records that they point to.&lt;/p&gt;  &lt;p&gt;A common example of this usage is the song browser in your own mp3 player application (for example, the iTunes application). This application will allow you to choose an mp3 file (the &lt;em&gt;detail&lt;/em&gt; record) based on criteria such as Artist, Album, Song (the &lt;em&gt;master&lt;/em&gt; record). Once the &lt;em&gt;master&lt;/em&gt; record is choosen (i.e., the Artist, Album and Song) it then performs a task on the &lt;em&gt;detail&lt;/em&gt; record (i.e., play the mp3 file).&lt;/p&gt;  &lt;p&gt;This &lt;strong&gt;Gtk2::Ex::RecordsFilter&lt;/strong&gt; widget is inspired by the iTunes song browser widget. But this widget carries certain functionality which is not present in the iTunes song browser. The iTunes song browser allows the user to choose one song (one &lt;em&gt;master&lt;/em&gt; record) at a time and play it. However, a more general usage should allow the user to choose multiple &lt;em&gt;master&lt;/em&gt; records at a time. One approach for such multiple selections is to enable the user to click on different records with the CTRL key pressed and then choose all the highlighted records in one shot. This widget takes a different approach, which I call the &lt;em&gt;'shopping cart'&lt;/em&gt; approach. This is explained in the next section.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;&lt;a name="user_interaction"&gt;&lt;span style="font-weight: bold;"&gt;USER INTERACTION&lt;/span&gt;&lt;br /&gt;&lt;/a&gt;The top half the widget shows all the master records. The records are shown in a hierarchical fashion similar to the iTunes song browser. Clicking on a parent node on the left-most box will cause all the boxes on its right to show &lt;strong&gt;only&lt;/strong&gt; the child nodes.  &lt;p&gt;The user can click on any entry in the top half and then click on the &lt;em&gt;add to selection&lt;/em&gt; button and the record will show up in the bottom half. If the entry clicked is in one of the left boxes, then the widget automatically discovers all the child nodes and adds them to the selection. Upon adding to selection, the record is removed from the top half and shows up in the bottom half. The &lt;em&gt;remove from selection&lt;/em&gt; button works in the reverse way.&lt;/p&gt;   &lt;p&gt;The user can click on multiple records in the top half using the CTRL key.&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/img/94/3118/640/filter.jpg"&gt;&lt;img style="border: 1px solid rgb(0, 0, 0); margin: 2px;" src="http://photos1.blogger.com/img/94/3118/320/filter.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;br /&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;METHODS&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;    &lt;br /&gt;&lt;a name="methods"&gt;&lt;/a&gt;  &lt;a name="gtk2__ex__recordsfilter_new"&gt;Gtk2::Ex::RecordsFilter-&gt;new&lt;/a&gt;   &lt;pre&gt;my $recordsfilter = Gtk2::Ex::RecordsFilter-&gt;new;&lt;/pre&gt;  &lt;p&gt;The widget can be used to select a subset of these records (into a selection list). The methods &lt;code&gt;get_selected_rows&lt;/code&gt; and &lt;code&gt;get_unselected_rows&lt;/code&gt; can be used to view the selection ( or unselection) at any point.&lt;/p&gt;  &lt;p&gt;'Selected' portion is referred to as the 'RIGHT' side (bottom). 'Unselected' portion is referred to as the 'LEFT' side (top)&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;a name="gtk2__ex__recordsfilter_set_data"&gt;Gtk2::Ex::RecordsFilter-&gt;set_data&lt;/a&gt;&lt;/p&gt;   &lt;p&gt; &lt;/p&gt;    &lt;pre&gt;$recordsfilter-&gt;set_data($recordset);&lt;/pre&gt;  &lt;p&gt;The recordset is injected into the widget using this method. The widget will automatically create the HPaned children and the Selection buttons.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;a name="gtk2__ex__recordsfilter_get_widget"&gt;Gtk2::Ex::RecordsFilter-&gt;get_widget&lt;/a&gt;&lt;/p&gt;   &lt;p&gt; &lt;/p&gt;    &lt;pre&gt;my $recordsfilter_widget = $recordsfilter-&gt;get_widget();&lt;/pre&gt;  &lt;p&gt;This method returns the widget of the filter object.&lt;a name="gtk2__ex__recordsfilter_get_selected_rows"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a name="gtk2__ex__recordsfilter_get_selected_rows"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;Gtk2::Ex::RecordsFilter-&gt;get_selected_rows&lt;/a&gt;&lt;/p&gt;   &lt;p&gt; &lt;/p&gt;    &lt;pre&gt;my $selected_rows = $recordsfilter-&gt;get_selected_rows();&lt;br /&gt;print Dumper $selected_rows;&lt;/pre&gt;  &lt;p&gt;This method returns the &lt;em&gt;selected_rows&lt;/em&gt; contained in the bottom half of filter widget. A common usage is to have an &lt;em&gt;Apply&lt;/em&gt; button which, when clicked, will invoke this method and use the returned results. Check out the examples directory to see this in action.&lt;/p&gt;  &lt;pre&gt;$apply_button-&gt;signal_connect (clicked =&gt;&lt;br /&gt;sub {&lt;br /&gt;  my $selected_rows = $recordsfilter-&gt;get_selected_rows();&lt;br /&gt;  print Dumper $selected_rows;&lt;br /&gt;}&lt;br /&gt;);&lt;a name="gtk2__ex__recordsfilter_get_unselected_rows"&gt;&lt;span style="font-family:georgia,serif;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;Gtk2::Ex::RecordsFilter-&gt;get_unselected_rows&lt;/a&gt;&lt;/pre&gt;  &lt;p&gt; &lt;/p&gt;    &lt;pre&gt;my $selected_rows = $recordsfilter-&gt;get_unselected_rows();&lt;br /&gt;print Dumper $selected_rows;&lt;/pre&gt;  &lt;p&gt;This method returns the &lt;em&gt;unselected_rows&lt;/em&gt; contained in the top half of filter widget. This method too can be used with an &lt;em&gt;Apply&lt;/em&gt; button like the one shown above.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;hr /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10312676-110936672256038080?l=ofey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ofey.blogspot.com/feeds/110936672256038080/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10312676&amp;postID=110936672256038080' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/110936672256038080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/110936672256038080'/><link rel='alternate' type='text/html' href='http://ofey.blogspot.com/2005/02/gtk2exrecordsfilter.html' title='Gtk2::Ex::RecordsFilter'/><author><name>Ofey</name><uri>http://www.blogger.com/profile/01522735009406306313</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10312676.post-110816409427711799</id><published>2005-02-11T15:21:00.000-08:00</published><updated>2005-02-11T15:26:03.506-08:00</updated><title type='text'>Gtk2::Ex::TreeMaker - 0.07</title><content type='html'>This is the 0.07 release of this widget. See &lt;a href="http://ofey.blogspot.com/2005/02/gtk2extreemaker.html"&gt;here&lt;/a&gt; for details on the widget including a screenshot&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;CHANGES&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;   &lt;li&gt;Added two more signals (cell-enter and cell-leave)&lt;/li&gt;   &lt;li&gt;These signals are applicable only for the 'hyperlinked' cells. Call-back will be called when the mouse enters or leaves a 'hyperlinked' cell.&lt;/li&gt;   &lt;li&gt;Updated the example to reflect the new capability&lt;/li&gt;   &lt;li&gt;Updated the documentation to reflect the new capability&lt;/li&gt; &lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10312676-110816409427711799?l=ofey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ofey.blogspot.com/feeds/110816409427711799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10312676&amp;postID=110816409427711799' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/110816409427711799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/110816409427711799'/><link rel='alternate' type='text/html' href='http://ofey.blogspot.com/2005/02/gtk2extreemaker-007.html' title='Gtk2::Ex::TreeMaker - 0.07'/><author><name>Ofey</name><uri>http://www.blogger.com/profile/01522735009406306313</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10312676.post-110793313241865836</id><published>2005-02-08T23:12:00.000-08:00</published><updated>2005-02-08T23:13:51.216-08:00</updated><title type='text'>Gtk2::Ex::TreeMaker - 0.06</title><content type='html'>This is the 0.06 release of this widget. See &lt;a href="http://ofey.blogspot.com/2005/02/gtk2extreemaker.html"&gt;here&lt;/a&gt; for details on the widget including a screenshot&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;CHANGES&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;   &lt;li&gt;Fixed the issue with the Makefile.pl&lt;/li&gt;   &lt;li&gt;Added tests (40 of them) to verify the model that is being created&lt;/li&gt;   &lt;li&gt;(Still to add tests for the UI events, cell-edited, cell-clicked etc)&lt;/li&gt;   &lt;li&gt;Cleaned up the API for setting the column_names.&lt;/li&gt; &lt;/ul&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10312676-110793313241865836?l=ofey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ofey.blogspot.com/feeds/110793313241865836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10312676&amp;postID=110793313241865836' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/110793313241865836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/110793313241865836'/><link rel='alternate' type='text/html' href='http://ofey.blogspot.com/2005/02/gtk2extreemaker-006.html' title='Gtk2::Ex::TreeMaker - 0.06'/><author><name>Ofey</name><uri>http://www.blogger.com/profile/01522735009406306313</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10312676.post-110755893613593091</id><published>2005-02-04T15:15:00.000-08:00</published><updated>2005-02-04T15:27:48.453-08:00</updated><title type='text'>Gtk2::Ex::TreeMaker - 0.05</title><content type='html'>This is the 0.05 release of this widget. See &lt;a href="http://ofey.blogspot.com/2005/02/gtk2extreemaker.html"&gt;here&lt;/a&gt; for details on the widget including a screenshot&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;CHANGES&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;   &lt;li&gt;Added a custom attribute called 'hyperlinked'. The mouse pointer changes when moved over a 'hyperlinked' cell. A specified call-back is called when the cell is clicked.&lt;/li&gt; &lt;li&gt;In addition to this custom attribute, any of the attributes of the Gtk2::CellRendererText can also be passed to this widget. (background, editable etc)&lt;br /&gt;&lt;/li&gt;    &lt;li&gt;Added signal handler for 'cell-clicked', 'cell-edited'. Cleaned up the code defining the signal_connect.&lt;br /&gt;&lt;/li&gt;   &lt;li&gt;Cleaned up code in other areas too.&lt;br /&gt;&lt;/li&gt;   &lt;li&gt;Updated documentation.&lt;br /&gt;&lt;/li&gt;   &lt;li&gt;Updated the MANIFEST to include the /examples.&lt;/li&gt; &lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10312676-110755893613593091?l=ofey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ofey.blogspot.com/feeds/110755893613593091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10312676&amp;postID=110755893613593091' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/110755893613593091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/110755893613593091'/><link rel='alternate' type='text/html' href='http://ofey.blogspot.com/2005/02/gtk2extreemaker-005.html' title='Gtk2::Ex::TreeMaker - 0.05'/><author><name>Ofey</name><uri>http://www.blogger.com/profile/01522735009406306313</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10312676.post-110739852529925555</id><published>2005-02-02T18:42:00.000-08:00</published><updated>2005-02-02T19:05:22.703-08:00</updated><title type='text'>Gtk2::Ex::TreeMaker</title><content type='html'>&lt;a href="http://sourceforge.net/project/showfiles.php?group_id=121463&amp;package_id=142803"&gt;&lt;strong&gt;Gtk2::Ex::TreeMaker&lt;/strong&gt;&lt;/a&gt; - A high level widget to represent a set of relational records in a hierarchical spreadsheet kinda display. This task is typical to most of the business application user interfaces.&lt;br /&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Description&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Typically in business applications, users like to view data in a spreadsheet kind of display. (Columns represent timeline (typically)&lt;code&gt;&lt;/code&gt; and rows represent measures like sales/inventory/blah/blah).&lt;/p&gt;  &lt;p&gt;The data itself is typically stored internally as relational records. For example, here is some sales info (stored internally in a relational database)&lt;/p&gt;  &lt;pre&gt;-------------------------------------&lt;br /&gt;Region, City, Product, Date, Quantity&lt;br /&gt;-------------------------------------&lt;br /&gt;Texas, Dallas, Fruits, Dec-2003, 300&lt;br /&gt;Texas, Dallas, Veggies, Jan-2004, 120&lt;br /&gt;Texas, Austin, Fruits, Nov-2003, 310&lt;br /&gt;Texas, Austin, Veggies, Feb-2004, 20&lt;br /&gt;-------------------------------------&lt;/pre&gt;  &lt;p&gt;The user will typically want to view the same data in a hierarchical (/spreadsheet)&lt;span style="font-family:monospace;"&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt; kinda display.&lt;/p&gt;  &lt;pre&gt;------------------------------------------------------&lt;br /&gt;Prod / Date   Nov-2003  Dec-2003  Jan-2004  Feb-2004&lt;br /&gt;------------------------------------------------------&lt;br /&gt;Texas&lt;br /&gt;Dallas&lt;br /&gt;  Fruits                  300       &lt;br /&gt;  Veggies                           120&lt;br /&gt;Austin&lt;br /&gt;  Fruits        310&lt;br /&gt;  Veggies                                     20&lt;br /&gt;------------------------------------------------------&lt;/pre&gt;  &lt;p&gt;With web-based business apps, similar views are created in the browser using lots of html/jsp coding.&lt;/p&gt;  &lt;p&gt;The Gtk2::TreeView is an excellent widget to display a similar presentation of data in a desktop app. But creating a (hierarchical) TreeView from flat relational data can require some recursive function coding. It would be great if all this recursive code could be abstracted out and packaged separately.&lt;/p&gt;  &lt;p&gt;This high level widget is designed with that purpose in mind. This module will accept a relational feed of records and automatically convert it into a hierarchical treeview using the Gtk2::TreeView. The process involves invoking some recursive functions to build a TreeModel and populate it. Also, since the spreadsheet itself can be rather long horizontally, the widget also has a &lt;em&gt;FreezePane&lt;/em&gt; capability.&lt;/p&gt;&lt;a href="http://photos1.blogger.com/img/94/3118/640/treemaker-3.jpg"&gt;&lt;img style="border: 1px solid rgb(0, 0, 0); margin: 2px;" src="http://photos1.blogger.com/img/94/3118/320/treemaker-3.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The above screenshot was generated using the following relational data (csv)&lt;br /&gt;&lt;pre&gt;__DATA__&lt;span style="font-family:georgia,serif;"&gt;&lt;br /&gt;&lt;/span&gt;#state,city,product,date,text,editable,underline,background&lt;span style="font-family:georgia,serif;"&gt;&lt;br /&gt;&lt;/span&gt;Texas,Dallas,Fruits,Dec-2003,300,0,1,red&lt;span style="font-family:georgia,serif;"&gt;&lt;br /&gt;&lt;/span&gt;Texas,Dallas,Veggies,Jan-2004,120,1,0,blue&lt;span style="font-family:georgia,serif;"&gt;&lt;br /&gt;&lt;/span&gt;Texas,Austin,Fruits,Nov-2003,310,1,0,white&lt;span style="font-family:georgia,serif;"&gt;&lt;br /&gt;&lt;/span&gt;Texas,Austin,Veggies,Feb-2004,20,0,1,red&lt;span style="font-family:georgia,serif;"&gt;&lt;br /&gt;&lt;/span&gt;Texas,Austin,Veggies,Jun-2004,80,0,0,red&lt;span style="font-family:georgia,serif;"&gt;&lt;br /&gt;&lt;/span&gt;California,LA,Veggies,Jun-2004,80,1,0,brown&lt;/pre&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10312676-110739852529925555?l=ofey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ofey.blogspot.com/feeds/110739852529925555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10312676&amp;postID=110739852529925555' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/110739852529925555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/110739852529925555'/><link rel='alternate' type='text/html' href='http://ofey.blogspot.com/2005/02/gtk2extreemaker.html' title='Gtk2::Ex::TreeMaker'/><author><name>Ofey</name><uri>http://www.blogger.com/profile/01522735009406306313</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10312676.post-110739695645938527</id><published>2005-02-02T18:14:00.000-08:00</published><updated>2005-02-04T07:37:56.286-08:00</updated><title type='text'>Gmail accounts</title><content type='html'>&lt;span style="text-decoration: line-through;"&gt;&lt;br /&gt;Every one seems to be talking about gmail these days.  I feel left out for not having one.&lt;br /&gt;&lt;br /&gt;If any one wants to send me an invite, please send it to&lt;br /&gt;ofey_aikon at yahoo dot com&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;:)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Wow! Thank you for all the invites that you guys have sent me. I'm gonna play with gmail now.&lt;/span&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10312676-110739695645938527?l=ofey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ofey.blogspot.com/feeds/110739695645938527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10312676&amp;postID=110739695645938527' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/110739695645938527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/110739695645938527'/><link rel='alternate' type='text/html' href='http://ofey.blogspot.com/2005/02/gmail-accounts.html' title='Gmail accounts'/><author><name>Ofey</name><uri>http://www.blogger.com/profile/01522735009406306313</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10312676.post-110662116868221535</id><published>2005-01-24T18:43:00.000-08:00</published><updated>2005-01-24T18:46:08.683-08:00</updated><title type='text'>I found a few more ppm repositories</title><content type='html'>I found a few more ppm repositories from this perlmonks &lt;a href="http://perlmonks.thepen.com/162391.html"&gt;thread&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ppd.develop-help.com/ppd/"&gt;http://ppd.develop-help.com/ppd/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.roth.net/perl/packages/"&gt;http://www.roth.net/perl/packages/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.xray.mpe.mpg.de/%7Each/ptk/ppm/"&gt;http://www.xray.mpe.mpg.de/~ach/ptk/ppm/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://theoryx5.uwinnipeg.ca/ppmpackages/"&gt;http://theoryx5.uwinnipeg.ca/ppmpackages/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://dada.perl.it/PPM"&gt;http://dada.perl.it/PPM&lt;/a&gt;&lt;br /&gt;&lt;a href="http://jenda.krynicky.cz/perl"&gt;http://jenda.krynicky.cz/perl&lt;/a&gt;&lt;br /&gt;&lt;a href="http://rto.dk/packages/"&gt;http://rto.dk/packages/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://openinteract.sourceforge.net/ppmpackages/"&gt;http://openinteract.sourceforge.net/ppmpackages/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://ppm.gingerall.cz"&gt;http://ppm.gingerall.cz&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.epn.ml.org/%7Espurkis/Agent/repository"&gt;http://www.epn.ml.org/~spurkis/Agent/repository &lt;/a&gt;&lt;br /&gt;&lt;a href="http://homepage.eircom.net/%7Ejmcnamara/perl"&gt;http://homepage.eircom.net/~jmcnamara/perl&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10312676-110662116868221535?l=ofey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ofey.blogspot.com/feeds/110662116868221535/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10312676&amp;postID=110662116868221535' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/110662116868221535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/110662116868221535'/><link rel='alternate' type='text/html' href='http://ofey.blogspot.com/2005/01/i-found-few-more-ppm-repositories.html' title='I found a few more ppm repositories'/><author><name>Ofey</name><uri>http://www.blogger.com/profile/01522735009406306313</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10312676.post-110646146020112492</id><published>2005-01-22T22:23:00.000-08:00</published><updated>2005-01-22T22:24:26.973-08:00</updated><title type='text'>DateTime.ppd for Activeperl</title><content type='html'>The folks at Activestate seem to be having trouble compiling the DateTime.pm module.&lt;br /&gt;&lt;br /&gt;Luckily I found a DateTime.ppd &lt;a href="http://theoryx5.uwinnipeg.ca/ppms/"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10312676-110646146020112492?l=ofey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ofey.blogspot.com/feeds/110646146020112492/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10312676&amp;postID=110646146020112492' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/110646146020112492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/110646146020112492'/><link rel='alternate' type='text/html' href='http://ofey.blogspot.com/2005/01/datetimeppd-for-activeperl.html' title='DateTime.ppd for Activeperl'/><author><name>Ofey</name><uri>http://www.blogger.com/profile/01522735009406306313</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10312676.post-110635153496049963</id><published>2005-01-21T15:52:00.000-08:00</published><updated>2005-01-22T23:44:29.310-08:00</updated><title type='text'>Gtk2::Ex::RecordsFilter</title><content type='html'>&lt;a href="http://search.cpan.org/%7Eofeyaikon/Gtk2-Ex-RecordsFilter-0.02/"&gt;&lt;b&gt;Gtk2::Ex::RecordsFilter&lt;/b&gt;&lt;/a&gt; - A high level widget to browse reasonably large amounts of relational data and select a subset of records. This widget is inspired by the song browser of iTunes.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;DESCRIPTION&lt;br /&gt;&lt;/b&gt;When working with large amounts of relational records (csv files, database records, music files index), a common task is to filter out a subset or records from a given set. For example, in a &lt;i&gt;master-detail&lt;/i&gt; database design, the &lt;i&gt;master&lt;/i&gt; recordset, which is typically smaller than the &lt;i&gt;detail&lt;/i&gt; recordset, can be filtered out and the filtered subset of &lt;i&gt;master&lt;/i&gt; records can then be used to perform additional tasks on the &lt;i&gt;detail&lt;/i&gt; records that they point to. &lt;p&gt;A common example of this usage is your own mp3 player application (for example, the iTunes application). This application will allow you to choose an mp3 file (the &lt;i&gt;detail&lt;/i&gt; record) based on criteria such as Artist, Album, Song (the &lt;i&gt;master&lt;/i&gt; record). Once the &lt;i&gt;master&lt;/i&gt; record is choosen (i.e., the Artist, Album and Song) it then performs a task on the &lt;i&gt;detail&lt;/i&gt; record (i.e., play the mp3 file).&lt;/p&gt;&lt;p&gt;This &lt;b&gt;Gtk2::Ex::RecordsFilter&lt;/b&gt; widget is inspired by the iTunes song browser widget. But this widget carries certain functionality which is not present in the iTunes song browser. The iTunes song browser allows the user to choose one song (one &lt;i&gt;master&lt;/i&gt; record) at a time and play it. However, a more general usage should allow the user to choose multiple &lt;i&gt;master&lt;/i&gt; records at a time. One approach for such multiple selections is to enable the user to click on different records with the CTRL key pressed and then choose all the highlighted records in one shot. This widget takes a different approach, which I call the &lt;i&gt;'shopping cart'&lt;/i&gt; approach. This is explained in the next section.&lt;br /&gt;&lt;/p&gt;&lt;b&gt;USER INTERACTION&lt;br /&gt;&lt;/b&gt;&lt;p&gt;The top half the widget shows all the master records. The records are shown in a hierarchical fashion similar to the iTunes song browser. Clicking on a parent node on the left-most box will cause all the boxes on its right to show &lt;b&gt;only&lt;/b&gt; the child nodes.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/img/94/3118/640/screenshot1-2.jpg"&gt;&lt;img style="border: 1px solid rgb(0, 0, 0); margin: 2px;" src="http://photos1.blogger.com/img/94/3118/320/screenshot1-2.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The user can click on any entry in the top half and then click on the &lt;i&gt;add to selection&lt;/i&gt; button and the record will show up in the bottom half. If the entry clicked is in one of the left boxes, then the widget automatically discovers all the child nodes and adds them to the selection. Upon adding to selection, the record is removed from the top half and shows up in the bottom half. The &lt;i&gt;remove from selection&lt;/i&gt; button works in the reverse way.&lt;/p&gt;&lt;p&gt;The user can click on multiple records in the top half using the CTRL key.&lt;/p&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10312676-110635153496049963?l=ofey.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ofey.blogspot.com/feeds/110635153496049963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10312676&amp;postID=110635153496049963' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/110635153496049963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10312676/posts/default/110635153496049963'/><link rel='alternate' type='text/html' href='http://ofey.blogspot.com/2005/01/gtk2exrecordsfilter.html' title='Gtk2::Ex::RecordsFilter'/><author><name>Ofey</name><uri>http://www.blogger.com/profile/01522735009406306313</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
