I'm working on a project of my own, which will ultimately have a very similar forward-sort/reverse-sort capability:
#!/usr/bin/perl -w # Strict use strict; use warnings; # Libraries use Tk; use Tk::ROText; # User-defined my $linux_browser = 'firefox'; my $win32_browser = 'C:\\PROGRA~1\\MOZILL~1\\FIREFOX.EXE'; my $headerfont = "Courier 10 bold"; my $textfont = "Courier 10"; my $urlfont = "Courier 10 italic"; my @colors = qw( peachpuff lightyellow ); my @columns = qw( Company Address Homepage ); my $p_col_widths = { 'Company' => 20, 'Address' => 20, 'Homepage' => + 28 }; my $pdata = [ ['General Electric', 'Fairfield, CT', 'www.ge.com' + ], ['FedEx', 'Memphis, TN', 'www.fedex.com' + ], ['Southwest Airlines', 'Dallas, TX', 'www.southwest.com' + ], ['Procter & Gamble', 'Cincinnati, OH', 'www.pg.com' + ], ['Starbucks', 'Seattle, WA', 'www.starbucks.com' + ], ['Johnson & Johnson', 'New Brunswick, NJ', 'www.jnj.com' + ], ['Berkshire Hathaway', 'Omaha, NE', 'www.berkshirehathaway +.com'], ['Dell', 'Round Rock, TX', 'www.dell.com' + ], ['Toyota', 'Toyota, Japan', 'www.toyota.co.jp' + ], ['Microsoft', 'Redmond, WA', 'www.microsoft.com' + ], ['Apple Computer', 'Cupertino, CA', 'www.apple.com' + ], ['Wal-Mart', 'Bentonville, AR', 'www.walmartstores.com +' ], ['UPS', 'Atlanta, GA', 'www.ups.com' + ], ['Home Depot', 'Atlanta, GA', 'www.homedepot.com' + ], ['PepsiCo', 'Purchase, NY', 'www.pepsico.com' + ], ['Costco', 'Issaquah, WA', 'www.costco.com' + ], ['American Express', 'New York, NY', 'www.americanexpress.c +om' ], ['Goldman Sachs', 'New York, NY', 'www.gs.com' + ], ['IBM', 'Armonk, NY', 'www.ibm.com' + ], ['3M', 'St. Paul, MN', 'www.3m.com' + ], ]; # Main program # Create the GUI my $mw = new MainWindow; my $f1 = $mw->Frame()->pack(-expand => 0, -fill => 'x'); my $f2 = $mw->Frame()->pack(-expand => 1, -fill => 'both'); button($f1, 'Exit', 'right', sub { $mw->destroy() }, "Escape"); my $txt = $f2->Scrolled('ROText', -scrollbars => 'osoe'); $txt->configure(-width => 90, -height => 32, -selectforeground => 'bla +ck'); $txt->pack(-expand => 1, -fill => 'both'); sort_by_column(1, 0); MainLoop; # Subroutines sub button { my ($w, $text, $side, $psub, $bind) = @_; ($bind || 0) and $text .= " ($bind)"; my $btn = $w->Button(-bg => 'skyblue', -text => $text); if ($psub || 0) { $btn->configure(-command => $psub); ($bind || 0) and $mw->bind("<$bind>" => sub { $btn->invoke() } +); } $btn->pack(-side => $side); return $btn; } sub sort_by_column { my ($idx, $order) = @_; # Delete all items in the Text widget $txt->delete("1.0", "end"); my $item_count = 0; # Display each column of the header for (my $i = 1; $i <= @columns; $i++) { my $text = my $column = $columns[$i - 1]; my $b_this_col = ($idx == $i)? 1: 0; $b_this_col and $text .= (0 == $order)? " (+)": " (-)"; my $width = $p_col_widths->{$column}; my $line = sprintf "| %-${width}.${width}s", $text; my $tag = "column_$column"; ($i == @columns) and $line .= "\n"; my $new_idx = $i; my $psub = sub { my $new_order = $b_this_col? 1 - $order: 0; sort_by_column($new_idx, $new_order); }; insert_item($line, '#ff7fef', $tag, $headerfont, $psub); } # Sort all data by the given field index my @sorted = $order? sort { $b->[$idx-1] cmp $a->[$idx-1] } @$pdat +a: sort { $a->[$idx-1] cmp $b->[$idx-1] } @$pdat +a; # Display each line of the data for (my $i = 0; $i < @sorted; $i++) { my $pcompany = $sorted[$i]; ++$item_count; my $color = $colors[$item_count % @colors]; for (my $j = 1; $j <= @columns; $j++) { my $column = $columns[$j-1]; my $data = $pcompany->[$j-1]; my $width = $p_col_widths->{$column}; my $line = sprintf "| %-${width}.${width}s", $data; ($j == @columns) and $line .= "\n"; my $tag = "item_${item_count}_$j"; if ($column eq 'Homepage') { my $psub = sub { launch_url($data) }; insert_item($line, $color, $tag, $urlfont, $psub); } else { insert_item($line, $color, $tag, $textfont); } } } } sub insert_item { my ($text, $bg, $tag, $font, $psub) = @_; $txt->tagConfigure($tag, -font => $font, -background => $bg); ($psub || 0) and make_text_hot($tag, $psub); $txt->insert("end", $text, $tag); } sub make_text_hot { my ($tag, $psub) = @_; my $p_enter_sub = sub { $txt->configure(-cursor => 'hand2') }; my $p_leave_sub = sub { $txt->configure(-cursor => 'xterm') }; $txt->tagBind($tag, "<Button-1>", $psub); $txt->tagBind($tag, "<Any-Enter>", $p_enter_sub); $txt->tagBind($tag, "<Any-Leave>", $p_leave_sub); } sub launch_url { my ($url) = @_; if ($^O =~ /win32/i) { # Startup the preferred Windows browser system("start $win32_browser \"$url\""); } else { # Child process runs the preferred Linux browser, parent retur +ns fork or exec "$linux_browser '$url'"; } }
The column which is sorted by changes its text to include either "(+)" for a forward sort, or "(-)" for a reverse sort. Furthermore, any URL in the homepage address column can be clicked on to bring that page up in a browser (the browsers are set according to the variables $linux_browser and $win32_browser).
In reply to Re: list overview sorted and colored rows
by liverpole
in thread list overview sorted and colored rows
by hudo
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |