Volume
2 Issue 3, March 2003 |
Copyright (C) 2003 by Steve Litt. All rights reserved. Materials from guest authors copyrighted by them and licensed for perpetual use to Linux Productivity Magazine. All rights reserved to the copyright holder, except for items specifically marked otherwise (certain free software source code, GNU/GPL, etc.). All material herein provided "As-Is". User assumes all risk and responsibility for any outcome.
and Rapid Learning: Secret Weapon of the Successful Technologist by Steve Litt |
[ Troubleshooters.Com
| Back Issues |Troubleshooting Professional Magazine
]
|
CONTENTS
2. You may make and give away verbatim copies of this Package for personal use, or for use within your organization, provided that you duplicate all of the original copyright notices and associated disclaimers. You may not distribute copies of this Package, or copies of packages derived from this Package, to others outside your organization without specific prior written permission from ActiveState (although you are encouraged to direct them to sources from which they may obtain it for themselves). |
#!/usr/bin/perl -w # ####################################################################### # Copyright (C) 2003 by Steve Litt, all rights reserved. # Licensed under version 2 of the GNU General Public License. # See http://www.troubleshooters.com/license.txt # or # http://www.gnu.org/licenses/gpl.txt # # ABSOLUTELY NO WARRANTY, USE AT YOUR OWN RISK! # require 5.003 ; use strict ; use Picklist ; ############################################################ # Construct a picklist using the Picklist Package # package Main ; use Tk ; ######################################## # Subroutine to call when user clicks the delete button on the picklist # sub myDeleteButtonEvent ( $$ ) { my $arg1 = shift ; my $rowNum = shift ; print "In myDeleteButtonEvent , arg1=$arg1 , rowNum=$rowNum\n" ; } ######################################## # Subroutine to call when user clicks the change button on the picklist # sub myChangeButtonEvent ( $$ ) { my $arg1 = shift ; my $rowNum = shift ; print "In myChangeButtonEvent , arg1=$arg1 , rowNum=$rowNum\n" ; } ######################################## # Subroutine to call when user clicks the add button on the picklist # sub myAddButtonEvent ( $$ ) { my $arg1 = shift ; my $rowNum = shift ; print "In myAddButtonEvent , arg1=$arg1 , rowNum=$rowNum\n" ; } ######################################## # This subroutine defines all the picklist's fields. Each field has a # name to go in the header, a length to be displayed, a justification # (right or left), a flag saying whether visible or invisible (it # might be included to return a lookup value, but not be visible). # # Additionally, exactly one field must be declared the KEY field, with # the $picklist->setKeyFieldNumber() method, and one field must be # declared the SORT field via the $picklist->setKeyFieldNumber() # method. # sub defineMyPicklistFields ( $ ) { my $picklist = shift ; my $field = 0 ; ######################################## # First field is president number # This field is the key returned from the picklist # $picklist->setFieldPrompt ( $field , "pNum" ) ; $picklist->setFieldLength ( $field , 5 ) ; $picklist->setFieldRightJustified ( $field ) ; $picklist->setFieldVisible ( $field ) ; $picklist->setKeyFieldNumber ( $field ) ; $field++ ; ######################################## # Second field is president's first name # $picklist->setFieldPrompt ( $field , "Fname" ) ; $picklist->setFieldLength ( $field , 9 ) ; $picklist->setFieldLeftJustified ( $field ) ; $picklist->setFieldVisible ( $field ) ; $field++ ; ######################################## # Third field is president's last name # This is the initial sort field # $picklist->setFieldPrompt ( $field , "Lname" ) ; $picklist->setFieldLength ( $field , 12 ) ; $picklist->setFieldLeftJustified ( $field ) ; $picklist->setFieldVisible ( $field ) ; $picklist->setSortFieldNumber ( $field ) ; $field++ ; ######################################## # Forth field is president's term of office # $picklist->setFieldPrompt ( $field , "Term" ) ; $picklist->setFieldLength ( $field , 9 ) ; $picklist->setFieldLeftJustified ( $field ) ; $picklist->setFieldVisible ( $field ) ; $field++ ; } ############################################################ # The loadMyPicklistWithRows() function does just what it says. It # repeatedly calls $picklist->addRow(), each call with a reference to # an array of all field values in the same order declared in the # defineMyPicklistFields() routine. # sub loadMyPicklistWithRows ( $ ) { my $picklist = shift ; $picklist->addRow ( [ 43 , "George" , "Bush" , "2001-????" ] ) ; $picklist->addRow ( [ 42 , "Bill" , "Clinton" , "1993-2000" ] ) ; $picklist->addRow ( [ 41 , "George" , "Bush" , "1989-1992" ] ) ; $picklist->addRow ( [ 40 , "Ronald" , "Reagan" , "1981-1988" ] ) ; $picklist->addRow ( [ 39 , "Jimmy" , "Carter" , "1977-1980" ] ) ; $picklist->addRow ( [ 38 , "Gerald" , "Ford" , "1974-1976" ] ) ; $picklist->addRow ( [ 37 , "Richard" , "Nixon" , "1963-1968" ] ) ; $picklist->addRow ( [ 36 , "Lyndon" , "Johnson" , "1963-1968" ] ) ; $picklist->addRow ( [ 35 , "John" , "Kennedy" , "1961-1963" ] ) ; $picklist->addRow ( [ 34 , "Dwight" , "Eisenhower" , "1953-1960" ] ) ; $picklist->addRow ( [ 33 , "Harry" , "Truman" , "1945-1952" ] ) ; $picklist->addRow ( [ 32 , "Franklin" , "Roosevelt" , "1933-1945" ] ) ; } ############################################################ # The main routine instantiates a picklist, calls # defineMyPicklistFields() and loadMyPicklistWithRows(), sets the # callbacks for the Add, Change and Delete buttons (none is needed for # the Pick and Escape actions). It then builds a small window to call # the picklist, and place the key value of the returned value in its # label. # # By default the Add, Change, Delete, Pick and Escape actions are # all enabled. If you want to disable some of those actions, use the # disableAdd(), disableChange(), disableDelete(), disablePick(), or # disableEscape() methods from the Picklist object. # # In practice, many picklists exist simply to pick a value, in which # case you'd disable Add, Change and Delete. Others are not called # from a field or form, but from the main program, to expose all # records for add, change or delete. In that case you'd disable pick. # And sometimes a picklist, called from a field to make a choice, also # allows add, change and delete. In that case you'd disable nothing. # # Picklists objects have many more settings. See the Picklist.pm # source code for details. # sub main() { print "\n\n\n" ; ######################################## # Build the Picklist object # my $picklist = Picklist->new() ; $picklist->setDefaultAction ( "PICK" ) ; # $picklist->disablePick() ; defineMyPicklistFields ( $picklist ) ; loadMyPicklistWithRows ( $picklist ) ; $picklist->setCallbackAdd ( [ \&Main::myAddButtonEvent , "dummy" ] ) ; $picklist->setCallbackChange ( [ \&Main::myChangeButtonEvent , "dummy" ] ) ; $picklist->setCallbackDelete ( [ \&Main::myDeleteButtonEvent , "dummy" ] ) ; ######################################## # Build the main window, which calls the picklist # my $mw = MainWindow->new() ; my $label = $mw->Label ( -text => 'Init' ) ->pack ( -side => 'top' , -anchor => 'w' ) ; my $butOk= $mw->Button ( -text => "Test" , -command => sub { $label->configure ( -text => $picklist->acquire ( $mw ) ) ; } ) ->pack() ->focus() ; my $butExit = $mw->Button ( -text => "Quit" , -command => sub { exit ; } ) ->pack() ; $mw->bind ( " |
$self->{'fields'}->[fieldnumber]->{'prompt'}Each field has a prompt (text displayed in its header button), a visibility (whether it appears on the Picklist), a left or right justification, and a display length. You might wonder why a field would be invisible. The answer is simple enough. The field might be included just because it's a unique key, capable of looking up the record, but the user has no reason to see this value. In this case you'd flag the field as invisible and as the key field, and then the field would be returned to the caller, even though the field is invisible.
$self->{'fields'}->[fieldnumber]->{'visible'}
$self->{'fields'}->[fieldnumber]->{'justification'}
$self->{'fields'}->[fieldnumber]->{'length'}
$self->{'rows'};Each element of the referenced array contains the following hash elements:
$self->{'rows'}->[$rowNum]->{'fields'}The {'fields'} part of the hash is, itself, a reference to an array comprised of the field values (not field properties -- field values).
$self->{'rows'}->[$rowNum]->{'sorttext'}
$self->{'rows'}->[$rowNum]->{'key'}
####################################################################### # Copyright (C) 2003 by Steve Litt, all rights reserved. # Licensed under version 1 of the # Litt Perl Development Tools License # See http://www.troubleshooters.com/licenses/LPDTL/COPYING.LPDTL.1.0 # # ABSOLUTELY NO WARRANTY, USE AT YOUR OWN RISK! # require 5.003 ; use strict; ###################################################################### # Package Picklist, implements a picklist. # # The picklist exposes the following actions: # Add # Change # Delete # Pick # Escape # # In all actions except the Escape action, the key field of the chosen # record is either sent to the callback (Add, Change, Delete) or # returned to the caller (Pick). The programmer configures the # Picklist object, declaring one of the fields to be the key field. In # database work, this would likely be the primary key of the table. # Because you sometimes do not want to show the key field to the user, # each field can be set invisible, in which case it won't show, nor # can it be sorted on (except initially). # # The Pick action terminates the picklist and returns the chosen # record to the caller. The Escape action terminates the picklist and # returns the magic number -999. Obviously future versions should # enable the user to specify the value returned on escape, but for the # time being -999 is a pretty good value. # # The Add, Change and Delete actions all call a programmer defined # callback function, and return to the picklist when that function # terminates. Typically that function would be a form on which you # could add or change a record, or a read-only form serving as a # confirmation of delete. # # Each row of the picklist can contain many fields, and clicking the # header button of that field will sort by that field. # package Picklist; use Tk; ############################################################ # The Picklist object constructor. It primarily sets defaults. # sub new($) { my($type) = $_[0]; my($self) = {}; bless($self, $type); $self->{'fields'} = []; # reference to an empty array $self->{'rows'} = []; # reference to an empty array $self->{'nextrownum'} = 0; $self->{'keyfield'} = 0; $self->{'sortfield'} = 0; ######################################## # Screen vars # $self->{'plfont'} = ["Fixed", "14", "bold"]; $self->{'helpfont'} = ["Fixed", "10", "bold"]; $self->{'title'} = "Pick one..."; $self->{'plheight'} = 0; $self->{'plwidth'} = 0; $self->{'addok'} = 1; $self->{'changeok'} = 1; $self->{'delok'} = 1; $self->{'pickok'} = 1; $self->{'escapeok'} = 1; $self->{'addkeys'} = [" |
addRow() | Application programmer uses this call to add a single
row to the picklist. The argument is a pointer to an array whose each element
is the contents of a field. |
formatField() | This formats a text string based on the the length
and justification properties of a field. An argument is available to tell
this method what character to use to fill empty space. For instance, in the
ListBox it's usually space, while in the header buttons it's typically a dash. |
char2string() | Makes a string comprised of the numeric argument length
of the character argument character. There's probably a Perl function to do
this, but I couldn't find it. |
getKeyFromIndex() |
Does what it says. Given the index returned by a selected
row of the ListBox, it peruses the array of rows for the contents of the field
number defined as the key field for the data. |
loadPickList() | This deletes everything out of the ListBox passed to
it and loads the ListBox with the elements of the array reference passed to
it. |
cat | grep this | grep that | sort | myprocessEvery step in that pipeline is a separate process that is assigned a processor, assuming there are enough processors. Because UNIX type processes are so light weight and involve so little overhead, procss startup causes very little latency. So what you basically have is that while myprocess works on record 1, sort works on record 2, grep that works on record 3, grep this works on record 4, and cat works on record 5. Obviously this is a gross simplification, but you get the idea.
Any article submitted to Linux Productivity Magazine must be licensed with the Open Publication License, which you can view at http://opencontent.org/openpub/. At your option you may elect the option to prohibit substantive modifications. However, in order to publish your article in Linux Productivity Magazine, you must decline the option to prohibit commercial use, because Linux Productivity Magazine is a commercial publication.
Obviously, you must be the copyright holder and must be legally able to so license the article. We do not currently pay for articles.
Troubleshooters.Com reserves the right to edit any submission for clarity or brevity, within the scope of the Open Publication License. If you elect to prohibit substantive modifications, we may elect to place editors notes outside of your material, or reject the submission, or send it back for modification. Any published article will include a two sentence description of the author, a hypertext link to his or her email, and a phone number if desired. Upon request, we will include a hypertext link, at the end of the magazine issue, to the author's website, providing that website meets the Troubleshooters.Com criteria for links and that the author's website first links to Troubleshooters.Com. Authors: please understand we can't place hyperlinks inside articles. If we did, only the first article would be read, and we can't place every article first.
Submissions should be emailed to Steve Litt's email address, with subject line Article Submission. The first paragraph of your message should read as follows (unless other arrangements are previously made in writing):
Copyright (c) 2003 by <your name>. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, version Draft v1.0, 8 June 1999 (Available at http://www.troubleshooters.com/openpub04.txt/ (wordwrapped for readability at http://www.troubleshooters.com/openpub04_wrapped.txt). The latest version is presently available at http://www.opencontent.org/openpub/).
Open Publication License Option A [ is | is not] elected, so this document [may | may not] be modified. Option B is not elected, so this material may be published for commercial purposes.
After that paragraph, write the title, text of the article, and a two sentence description of the author.
Q: What do you think about Extreme Linux, which allows clusters of low-end PCs to be linked together into powerful parallel processing supercomputers? A: Extreme Linux interested me because, first and foremost, I've always been an advocate of bigger and faster. Every CPU cycle you give me, I'll find a use for it. The concept of being able to make a supercomputer out of multiple PCs that offers somebody that much power -- basically at about a 40th of the price of a conventional supercomputer -- I just thought that was phenomenal. |