#!/usr/bin/perl
# gSequence - Protein Sequence Control Panel
# by Lorenz Pollsk
#
# this is work in progress! use this only for testing
use Gtk;
use strict;
use Bio::Seq;
use Bio::SeqIO;
use Bio::Tools::SeqStats;
use Bio::SeqFeature::Generic;
use Bio::Index::Abstract;
use Bio::DB::GenBank;
use Bio::DB::GenPept;
init Gtk;
# constant
my $false = 0;
my $true = 1;
# global widgets
my ($main_notebook,@main_label,@seq_edit);
my $about_dialog;
my ($import_dialog,$import_entry,@import_buttons,$import_from);
my ($description_window,$description_edit);
my ($comment_window,$comment_edit,$current_comment,$comment_frame);
my ($seqstats_window,$seqstats_edit);
my ($dblink_window,@dblink_entry,$current_dblink,$dblink_clist,$dblink_handler_id);
my ($ref_window,@ref_entry,$current_ref,$ref_clist,$ref_handler_id);
my ($feature_window,@feature_entry,$current_feature_item,@feature_spinner,
$feature_handler_id,$feature_tree);
my ($pref_window,@pref_entry);
# global file data
my @seq;
my @filename;
my @modified;
my @locked; # locked sequence for editing ?
my $current;
# menu
my @menu_items = ( { path => '/_File',
type => '<Branch>' },
{ path => '/File/_New',
accelerator => '<control>N',
callback => \&new },
{ path => '/File/_Open SwissProt',
accelerator => '<control>O',
callback => \&open_dialog },
{ path => '/File/_Save SwissProt',
accelerator => '<control>S',
callback => \&save },
{ path => '/File/Save _As...',
callback => \&saveas_dialog },
{ path => '/File/Close',
callback => \&close },
{ path => '/File/sep1',
type => '<Separator>' },
{ path => '/File/_Import from...',
type => '<Branch>' },
{ path => '/File/Import from.../Remote DB',
type => '<Branch>' },
{ path => '/File/Import from.../Remote DB/AceDB',
callback => sub { &seq_import("ace"); } },
{ path => '/File/Import from.../Remote DB/GenPept',
callback => sub { &seq_import("genpept"); } },
{ path => '/File/Import from.../Flat File Index',
type => '<Branch>' },
{ path => '/File/Import from.../Flat File Index/Fasta',
callback => sub { &seq_import("fasta"); } },
{ path => '/File/Import from.../Flat File Index/SwissProt',
callback => sub { &seq_import("swissprot"); } },
{ path => '/File/Import from.../Flat File Index/SwissPfam',
callback => sub { &seq_import("swisspfam"); } },
{ path => '/File/_Export to...' },
{ path => '/File/sep2',
type => '<Separator>' },
{ path => '/File/_Quit',
callback => sub { Gtk->exit( 0 ); } },
{ path => '/_Edit',
type => '<Branch>' },
{ path => '/Edit/C_ut',
callback => sub { $seq_edit[$current]->cut_clipboard(); },
accelerator => '<control>X' },
{ path => '/Edit/_Copy',
callback => sub { $seq_edit[$current]->copy_clipboard(); },
accelerator => '<control>C' },
{ path => '/Edit/_Paste',
callback => sub { $seq_edit[$current]->paste_clipboard(); },
accelerator => '<control>V' },
{ path => '/Edit/Select All',
callback => sub { $seq_edit[$current]->select_region(0,-1); } },
{ path => '/_Specs',
type => '<Branch>' },
{ path => '/Specs/_Sequence Stats',
callback => sub {&update_seqstats_window(1);} },
{ path => '/Specs/sep1',
type => '<Separator>' },
{ path => '/Specs/_Description',
callback => sub {&update_description_window(1);} },
{ path => '/Specs/_Comments',
callback => sub {&update_comment_window(1);} },
{ path => '/Specs/_DB Links',
callback => sub {&update_dblink_window(1);} },
{ path => '/Specs/_References',
callback => sub {&update_reference_window(1);} },
{ path => '/Specs/sep2',
type => '<Separator>' },
{ path => '/Specs/_Features',
callback => sub {&update_feature_window(1);} },
{ path => '/_Tools',
type => '<Branch>' },
{ path => '/Tools/Code Table' },
{ path => '/Tools/sep1',
type => '<Separator>' },
{ path => '/Tools/local Blast' },
{ path => '/Tools/local HMMER' },
{ path => '/Tools/hmmpfam' },
{ path => '/Tools/web Blast' },
{ path => '/_Options',
type => '<Branch>' },
{ path => '/Options/_Preferences',
callback => sub {&update_pref_window(1);} },
{ path => '/_Help',
type => '<LastBranch>' },
{ path => '/Help/Help' },
{ path => '/Help/_About...',
callback => sub { $about_dialog->show_all();} } );
### main
$current = 0;
&init_windows();
main Gtk;
exit( 0 );
### Subroutines
sub init_windows
{
&init_main_window();
&init_about_dialog();
&init_import_dialog();
&init_seqstats_window();
&init_description_window();
&init_comment_window();
&init_dblink_window();
&init_reference_window();
&init_feature_window();
&init_pref_window();
}
sub init_main_window
{
# toplevel window
my $window;
$window = new Gtk::Window( 'toplevel' );
$window->signal_connect( 'destroy', sub { Gtk->exit( 0 ); } );
$window->set_title( "gSequence" );
$window->set_usize( 600, 400 );
# vertical box containing menu and text editor widget
my $main_vbox;
$main_vbox = new Gtk::VBox( $false, 1 );
$main_vbox->border_width( 1 );
$window->add( $main_vbox );
# handlebox for menubar
my $handlebox;
$handlebox = new Gtk::HandleBox();
$main_vbox->pack_start( $handlebox, $false, $true, 0 );
# menubar
my $menubar;
$menubar = get_menu( $window );
$handlebox->add( $menubar );
# text widget
$seq_edit[$current] = new Gtk::Text( undef, undef );
$seq_edit[$current]->set_editable( $true );
# vertical scrollbar for text widget
my $scrollbar;
$scrollbar = new Gtk::VScrollbar( $seq_edit[$current]->vadj );
# horizontal box containing text widget and scrollbar
my $seq_edit_hbox;
$seq_edit_hbox = new Gtk::HBox( $false, 1 );
$seq_edit_hbox->border_width( 1 );
$seq_edit_hbox->pack_start( $seq_edit[$current], $true, $true, 0);
$seq_edit_hbox->pack_end( $scrollbar, $false, $true, 0);
$main_notebook = new Gtk::Notebook();
$main_notebook->set_tab_pos( 'top' );
$main_vbox->pack_end( $main_notebook, $true, $true, 0);
# show everything
$window->show_all();
$main_notebook->signal_connect_after("switch-page",
sub{ #$seq[$current]->seq($seq_edit[$current]->get_chars(0,-1))
# if (defined($seq[$current]));
$current = $main_notebook->get_current_page();
&update_seq_data(); } );
}
sub get_menu
{
my ( $window ) = @_;
my $menubar;
my $item_factory;
my $accel_group;
$accel_group = new Gtk::AccelGroup();
# This function initializes the item factory.
# Param 1: The type of menu - can be 'Gtk::MenuBar', 'Gtk::Menu',
# or 'Gtk::OptionMenu'.
# Param 2: The path of the menu.
# Param 3: The accelerator group. The item factory sets up
# the accelerator table while generating menus.
$item_factory = new Gtk::ItemFactory( 'Gtk::MenuBar',
'<main>',
$accel_group );
# This function generates the menu items. Pass the item factory,
# the number of items in the array, the array itself, and any
# callback data for the the menu items.
$item_factory->create_items( @menu_items );
# Attach the new accelerator group to the window.
$window->add_accel_group( $accel_group );
# Finally, return the actual menu bar created by the item factory.
#*menubar = gtk_item_factory_get_widget (item_factory, "<main>");
return ( $item_factory->get_widget( '<main>' ) );
}
sub new_seq_page
{
my ($seq) = shift;
my $curr;
push @seq,$seq;
$curr = @seq - 1;
$main_label[$curr] = new Gtk::Label($seq[$curr]->id())
if (defined($seq[$curr]));
$main_label[$curr] = new Gtk::Label("<New>")
if (!defined($seq[$curr]));
# text widget
$seq_edit[$curr] = new Gtk::Text( undef, undef );
$seq_edit[$curr]->set_editable( $true );
# vertical scrollbar for text widget
my $scrollbar;
$scrollbar = new Gtk::VScrollbar( $seq_edit[$curr]->vadj );
# horizontal box containing text widget and scrollbar
my $seq_edit_hbox;
$seq_edit_hbox = new Gtk::HBox( $false, 1 );
$seq_edit_hbox->border_width( 1 );
$seq_edit_hbox->pack_start( $seq_edit[$curr], $true, $true, 0);
$seq_edit_hbox->pack_end( $scrollbar, $false, $true, 0);
$main_notebook->append_page( $seq_edit_hbox, $main_label[$curr] );
$main_notebook->show_all();
$main_notebook->set_page(-1);
}
sub seq_fetch
{
my ($server,$port,$dir,$db); # read from preferences
my ($dbobj);
return if (!defined($import_from) || !($import_from));
$dbobj = Bio::DB::GenPept->new() if ($import_from eq "genpept");
$dbobj = Bio::DB::Ace->new(-host=>$server,-port=>$port)
if ($import_from eq "ace");
$dbobj = Bio::Index::Abstract->new("$dir/$db")
if ($import_from eq "fasta") ||
($import_from eq "swissprot") ||
($import_from eq "swisspfam");
if( $import_buttons[0]->get_active() ) {
&new_seq_page($dbobj->get_Seq_by_id($import_entry->get_text()));
} else {
&new_seq_page($dbobj->get_Seq_by_acc($import_entry->get_text()));
}
}
sub seq_import
{
($import_from) = @_;
my %names = ( "ace" => "AceDB",
"genpept" => "GenPept DB",
"fasta" => "Fasta Flat File",
"swissprot" => "SwissProt Flat File",
"swisspfam" => "SwissPfam Flat File"
);
$import_dialog->set_title("Import from ".$names{$import_from});
$import_entry->set_text("");
$import_dialog->show_all();
}
sub init_import_dialog
{
$import_dialog = new Gtk::Dialog();
$import_dialog->border_width(5);
# create the first button and add it to a box
my $button = new Gtk::RadioButton( "Fetch by ID" );
$import_dialog->vbox->pack_start($button,$false,$false,2);
# create the second button and add it to a box
$button = new Gtk::RadioButton( "Fetch by ACCESSION", $button );
$import_dialog->vbox->pack_start($button,$false,$false,2);
@import_buttons = $button->group();
$import_entry = new Gtk::Entry();
my $frame = new Gtk::Frame("Enter here:");
$frame->add($import_entry);
$import_dialog->vbox->pack_start( $frame, $true, $true, 5);
my $bbox = new Gtk::HButtonBox();
$bbox->set_layout("end");
$button = new Gtk::Button( "OK" );
$bbox->add( $button );
$button->signal_connect("clicked",
# OK button handler
sub{ $import_dialog->hide();
&seq_fetch();
});
$button = new Gtk::Button( "Cancel" );
$bbox->add( $button );
$button->signal_connect("clicked",
# close button handler
sub{ $import_dialog->hide();
});
$import_dialog->action_area->pack_start( $bbox, $true, $true, 0 );
$import_dialog->signal_connect_after( "delete_event",
# window delete handler
sub{ $import_dialog->hide();
return &Gtk::true;
});
}
sub open_dialog
{
# Create a new file selection widget
my $open_dialog = new Gtk::FileSelection( "Open File..." );
# Connect the ok_button to open_ok_sel function
$open_dialog->ok_button->signal_connect( "clicked",
\&ok_open_dialog,
$open_dialog );
# Connect the cancel_button to destroy the widget
$open_dialog->cancel_button->signal_connect( "clicked",
sub { $open_dialog->destroy(); } );
$open_dialog->show();
}
# Get the selected filename
sub ok_open_dialog
{
my ( $widget, $file_selection ) = @_;
push @filename, $file_selection->get_filename();
$widget->parent->parent->parent->destroy();
my $in = Bio::SeqIO->new(-file => $filename[-1] , '-format' => 'swiss');
&new_seq_page($in->next_seq());
}
sub update_seq_data
{
$main_label[$current]->set_text($seq[$current]->id) if (defined($seq[$current]));
$main_label[$current]->set_text("<New>") if (!defined($seq[$current]));
$seq_edit[$current]->freeze();
$seq_edit[$current]->delete_text(0,-1);
$seq_edit[$current]->insert(undef,undef,undef,$seq[$current]->seq()) if (defined($seq[$current]));
$seq_edit[$current]->thaw();
&update_comment_window();
&update_description_window();
&update_seqstats_window();
&update_dblink_window();
&update_reference_window();
&update_feature_window();
}
sub new
{
&new_seq_page(undef);
}
sub close
{
}
sub save
{
if (!defined($filename[$current])||!$filename[$current])
{
&saveas_dialog;
return;
}
my $out = Bio::SeqIO->new(-file => ">$filename[$current]" , '-format' => 'swiss');
$out->write_seq($seq[$current]);
}
sub saveas_dialog
{
# Create a new file selection widget
my $saveas_dialog = new Gtk::FileSelection( "Save As..." );
# Connect the ok_button to saveas_ok_sel function
$saveas_dialog->ok_button->signal_connect( "clicked",
\&ok_saveas_dialog,
$saveas_dialog );
# Connect the cancel_button to destroy the widget
$saveas_dialog->cancel_button->signal_connect( "clicked",
sub { $saveas_dialog->destroy(); } );
$saveas_dialog->show();
}
# Get the selected filename and print it to the console
sub ok_saveas_dialog
{
my ( $widget, $file_selection ) = @_;
my $filename = $file_selection->get_filename();
$widget->parent->parent->parent->destroy();
$filename[$current] = $filename;
my $out = Bio::SeqIO->new(-file => ">$filename[$current]" , '-format' => 'swiss');
$out->write_seq($seq[$current]);
}
sub init_comment_window
{
$current_comment = 0;
$comment_window = new Gtk::Dialog();
$comment_window->set_default_size(650,300);
$comment_window->set_policy($false,$true,$false);
$comment_window->set_title("Comments");
$comment_window->border_width(5);
# frame
$comment_frame = new Gtk::Frame( "Comment[".$current_comment."]" );
# text widget
$comment_edit = new Gtk::Text( undef, undef );
$comment_edit->set_editable( $true );
$comment_edit->set_word_wrap( $true );
# vertical scrollbar for text widget
my $scrollbar;
$scrollbar = new Gtk::VScrollbar( $comment_edit->vadj );
# horizontal box containing text widget and scrollbar
my $hbox;
$hbox = new Gtk::HBox( $false, 1 );
$hbox->border_width( 1 );
$hbox->pack_start( $comment_edit, $true, $true, 0);
$hbox->pack_end( $scrollbar, $false, $true, 0);
$comment_frame->add($hbox);
$comment_window->vbox->pack_start( $comment_frame, $true, $true, 5);
my $bbox = new Gtk::HBox( $false, 5 );
$bbox->border_width(10);
my $arrow = new Gtk::Arrow('right','out');
my $button = new Gtk::Button();
$button->add($arrow);
$bbox->pack_end( $button, $false, $false, 0);
$button->signal_connect
( "clicked",
# next comment button handler
sub { return if !defined($seq[$current]);
&store_current_comment;
$current_comment
if ($current_comment <((scalar $seq[$current]->annotation->each_Comment)-1));
&update_comment_window;
} );
$arrow = new Gtk::Arrow('left','out');
$button = new Gtk::Button();
$button->add($arrow);
$bbox->pack_end( $button, $false, $false, 0);
$button->signal_connect( "clicked",
# prev comment button handler
sub { return if !defined($seq[$current]);
&store_current_comment;
$current_comment--
if ($current_comment > 0);
&update_comment_window;
} );
$button = new Gtk::Button("Add");
$bbox->pack_start( $button, $false, $false, 0);
$button->signal_connect( "clicked",
# add comment button handler
sub { return if !defined($seq[$current]);
&store_current_comment;
my $comment = new Bio::Annotation::Comment;
$comment->text("");
$seq[$current]->annotation->add_Comment( $comment );
$current_comment = $seq[$current]->annotation->each_Comment - 1;
&update_comment_window;
} );
$button = new Gtk::Button("Delete");
$bbox->pack_start( $button, $false, $false, 0);
$button->signal_connect( "clicked",
# delete comment button handler
sub { return if !defined($seq[$current]);
$seq[$current]->annotation->remove_Comment( $current_comment );
$current_comment = $current_comment - 1
if ($current_comment > 0);
&update_comment_window;
} );
$comment_window->vbox->pack_end( $bbox, $false, $false, 0);
$bbox = new Gtk::HButtonBox();
$bbox->set_layout("end");
$button = new Gtk::Button( "Close" );
$bbox->add( $button );
$button->signal_connect("clicked",
# close button handler
sub{ $comment_window->hide();
&store_current_comment;
});
$comment_window->action_area->pack_start( $bbox, $true, $true, 0 );
$comment_window->signal_connect_after( "delete_event",
# window delete handler
sub{ $comment_window->hide();
&store_current_comment;
return &Gtk::true;
});
}
sub store_current_comment
{
(($seq[$current]->annotation->each_Comment)[$current_comment])->
text($comment_edit->get_chars(0,-1) )
if ((defined($seq[$current])) && ($seq[$current]->annotation->each_Comment));
}
sub update_comment_window
{
my ($show_me) = @_;
$comment_frame->set_label("Comment[".$current_comment."]");
# insert comment text
$comment_edit->freeze();
$comment_edit->delete_text(0,-1);
if (defined($seq[$current]))
{
my @comment = $seq[$current]->annotation->each_Comment;
$comment_edit->insert(undef,undef,undef, $comment[$current_comment]->text)
if (@comment);
}
$comment_edit->thaw();
$comment_window->show_all() if (defined($show_me));
}
sub init_description_window
{
$description_window = new Gtk::Dialog();
$description_window->set_default_size(620,250);
$description_window->border_width(5);
$description_window->set_title("Description");
# frame
my $description_frame = new Gtk::Frame( "Description" );
# text widget
$description_edit = new Gtk::Text( undef, undef );
$description_edit->set_editable( $true );
$description_edit->set_word_wrap( $true );
# vertical scrollbar for text widget
my $scrollbar;
$scrollbar = new Gtk::VScrollbar( $description_edit->vadj );
# horizontal box containing text widget and scrollbar
my $hbox;
$hbox = new Gtk::HBox( $false, 1 );
$hbox->border_width( 1 );
$hbox->pack_start( $description_edit, $true, $true, 0);
$hbox->pack_end( $scrollbar, $false, $true, 0);
$description_frame->add($hbox);
$description_window->vbox->pack_start( $description_frame, $true, $true, 5);
my $bbox = new Gtk::HButtonBox();
$bbox->set_layout("end");
my $button = new Gtk::Button( "Close" );
$bbox->add( $button );
$button->signal_connect("clicked",
# close button handler
sub{ $description_window->hide();
$seq[$current]->desc($description_edit->get_chars(0,-1))
if $description_edit->get_chars(0,-1);
});
$description_window->action_area->pack_start( $bbox, $true, $true, 0 );
$description_window->signal_connect_after( "delete_event",
# window delete handler
sub{ $description_window->hide();
$seq[$current]->desc($description_edit->get_chars(0,-1))
if $description_edit->get_chars(0,-1);
return &Gtk::true;
});
}
sub update_description_window
{
my ($show_me) = @_;
$description_edit->freeze();
$description_edit->delete_text(0,-1);
$description_edit->insert(undef,undef,undef,$seq[$current]->desc)
if defined($seq[$current]) && defined($seq[$current]->desc);
$description_edit->thaw();
$description_window->show_all() if (defined($show_me));
}
sub init_seqstats_window
{
$seqstats_window = new Gtk::Dialog();
$seqstats_window->border_width(5);
$seqstats_window->set_default_size(100,250);
$seqstats_window->set_title("Sequence Statistics");
# frame
my $seqstats_frame = new Gtk::Frame( "Sequence Statistics" );
# text widget
$seqstats_edit = new Gtk::Text( undef, undef );
$seqstats_edit->set_editable( $false );
$seqstats_edit->set_word_wrap( $true );
# vertical scrollbar for text widget
my $scrollbar;
$scrollbar = new Gtk::VScrollbar( $seqstats_edit->vadj );
# horizontal box containing text widget and scrollbar
my $hbox;
$hbox = new Gtk::HBox( $false, 1 );
$hbox->border_width( 1 );
$hbox->pack_start( $seqstats_edit, $true, $true, 0);
$hbox->pack_end( $scrollbar, $false, $true, 0);
$seqstats_frame->add($hbox);
$seqstats_window->vbox->pack_start( $seqstats_frame, $true, $true, 5);
my $bbox = new Gtk::HButtonBox();
$bbox->set_layout("end");
my $button = new Gtk::Button( "Close" );
$bbox->add( $button );
$button->signal_connect("clicked",
# close button handler
sub{ $seqstats_window->hide();
});
$seqstats_window->action_area->pack_start( $bbox, $true, $true, 0 );
$seqstats_window->signal_connect_after( "delete_event",
# window delete handler
sub{ $seqstats_window->hide();
return &Gtk::true;
});
}
sub update_seqstats_window
{
my ($show_me) = @_;
my ($data,$weight,$count_hash,$percent);
$seqstats_edit->freeze();
$seqstats_edit->delete_text(0,-1);
if (defined($seq[$current]))
{
$data = $seq[$current]->id."\n\n";
$weight = Bio::Tools::SeqStats->get_mol_wt($seq[$current]->primary_seq);
if ($$weight[0] == $$weight[1]) {
$data .= "Molecular weight of sequence equals to ".$$weight[0]."\n\n";
} else {
$data .= "Molecular weight of sequence is greater than ";
$data .= $$weight[0]." and less than ".$$weight[1]."\n\n";
}
$count_hash = Bio::Tools::SeqStats->count_monomers($seq[$current]->primary_seq);
$data .= "Amino Acids:\n";
foreach (sort keys %$count_hash)
{
$percent = sprintf "%.1f",
(($$count_hash{$_} / $seq[$current]->length)*100);
$data .= "${_}: ".$$count_hash{$_}." (${percent}%) \n"
}
$seqstats_edit->insert(undef,undef,undef,$data)
}
$seqstats_edit->thaw();
$seqstats_window->show_all() if (defined($show_me));
}
sub init_dblink_window
{
$current_dblink = 0;
$dblink_window = new Gtk::Dialog();
$dblink_window->set_default_size(500,400);
$dblink_window->set_policy($true,$true,$false);
$dblink_window->set_title("Database Links");
$dblink_window->border_width(5);
# Create a scrolled window to pack the CList widget into
my $scrolled_window = new Gtk::ScrolledWindow( undef, undef );
$dblink_window->vbox->pack_start( $scrolled_window, $true, $true, 0 );
$scrolled_window->set_policy( 'automatic', 'always' );
# Create the CList. For this example we use 2 columns
$dblink_clist = new_with_titles Gtk::CList( "Primary Id","Database" );
# When a selection is made, we want to know about it. The callback
# used is selection_made, and its code can be found further down
$dblink_handler_id = $dblink_clist->signal_connect( "select_row",
sub{ return if (!defined($seq[$current]));
my ( $clist, $row ) = @_;
&store_current_dblink;
$current_dblink = $row;
&update_dblink_window;
} );
# It isn't necessary to shadow the border, but it looks nice :)
$dblink_clist->set_shadow_type( 'out' );
# What however is important, is that we set the column widths as
# they will never be right otherwise. Note that the columns are
# numbered from 0 and up (to 1 in this case).
$dblink_clist->set_column_width( 0, 150 );
# Add the CList widget to the vertical box
$scrolled_window->add( $dblink_clist );
my $bbox = new Gtk::HBox( $false, 5 );
$bbox->border_width(10);
my $arrow = new Gtk::Arrow('down','out');
my $button = new Gtk::Button();
$button->add($arrow);
$bbox->pack_end( $button, $false, $false, 0);
$button->signal_connect
( "clicked",
# next dblink button handler
sub { return if (!defined($seq[$current]));
&store_current_dblink;
$current_dblink
if ($current_dblink <((scalar $seq[$current]->annotation->each_DBLink)-1));
&update_dblink_window;
} );
$arrow = new Gtk::Arrow('up','out');
$button = new Gtk::Button();
$button->add($arrow);
$bbox->pack_end( $button, $false, $false, 0);
$button->signal_connect( "clicked",
# prev comment button handler
sub { return if (!defined($seq[$current]));
&store_current_dblink;
$current_dblink--
if ($current_dblink > 0);
&update_dblink_window;
} );
$button = new Gtk::Button("Add");
$bbox->pack_start( $button, $false, $false, 0);
$button->signal_connect( "clicked",
# add comment button handler
sub { return if (!defined($seq[$current]));
&store_current_dblink;
my $dblink = new Bio::Annotation::DBLink;
$dblink->primary_id("<New>");
$seq[$current]->annotation->add_DBLink( $dblink );
$current_dblink = $seq[$current]->annotation->each_DBLink - 1;
$dblink_clist->append("","");
&update_dblink_window;
} );
$button = new Gtk::Button("Delete");
$bbox->pack_start( $button, $false, $false, 0);
$button->signal_connect( "clicked",
# delete comment button handler
sub { return if !defined($seq[$current]);
$seq[$current]->annotation->remove_DBLink( $current_dblink );
$dblink_clist->remove($current_dblink);
$current_dblink-- if ($current_dblink > 0);
&update_dblink_window;
} );
$dblink_window->vbox->pack_start( $bbox, $false, $false, 0);
# horizontal box containing primary_id & optional_id entries
my $hbox;
$hbox = new Gtk::HBox( $true, 10 );
$hbox->border_width( 1 );
# text entries
$dblink_entry[0] = new Gtk::Entry();
my $frame = new Gtk::Frame("primary id");
$frame->add($dblink_entry[0]);
$hbox->pack_start( $frame, $true, $true, 0);
$dblink_entry[1] = new Gtk::Entry();
$frame = new Gtk::Frame("optional id");
$frame->add($dblink_entry[1]);
$hbox->pack_end( $frame, $true, $true, 0);
$dblink_window->vbox->pack_start( $hbox, $false, $false, 5);
$dblink_entry[2] = new Gtk::Entry();
$frame = new Gtk::Frame("Database");
$frame->add($dblink_entry[2]);
$dblink_window->vbox->pack_start( $frame, $false, $false, 5);
$dblink_entry[3] = new Gtk::Entry();
$frame = new Gtk::Frame("Comment");
$frame->add($dblink_entry[3]);
$dblink_window->vbox->pack_end( $frame, $false, $false, 5);
$bbox = new Gtk::HButtonBox();
$bbox->set_layout("end");
$button = new Gtk::Button( "Close" );
$bbox->add( $button );
$button->signal_connect("clicked",
# close button handler
sub{ $dblink_window->hide();
&store_current_dblink;
});
$dblink_window->action_area->pack_start( $bbox, $true, $true, 0 );
$dblink_window->signal_connect_after( "delete_event",
# window delete handler
sub{ $dblink_window->hide();
&store_current_dblink;
return &Gtk::true;
});
}
sub store_current_dblink
{
if ((defined($seq[$current])) && ($seq[$current]->annotation->each_DBLink))
{
(($seq[$current]->annotation->each_DBLink)[$current_dblink])->
primary_id($dblink_entry[0]->get_chars(0,-1) );
(($seq[$current]->annotation->each_DBLink)[$current_dblink])->
optional_id($dblink_entry[1]->get_chars(0,-1) );
(($seq[$current]->annotation->each_DBLink)[$current_dblink])->
database($dblink_entry[2]->get_chars(0,-1) );
(($seq[$current]->annotation->each_DBLink)[$current_dblink])->
comment($dblink_entry[3]->get_chars(0,-1) );
}
}
sub update_dblink_window
{
my ($show_me) = @_;
$dblink_window->show_all() if (defined($show_me));
$dblink_clist->freeze();
if (!defined($seq[$current]))
{
$dblink_clist->clear();
$dblink_clist->thaw();
foreach (@dblink_entry) { $_->set_text(""); }
return;
}
my @dblinks = $seq[$current]->annotation->each_DBLink;
# reset clist if rows are different to links
if ($dblink_clist->rows != @dblinks) {
$dblink_clist->clear();
foreach (@dblinks) { $dblink_clist->append("",""); }
}
# redraw references
for(my $i=0;$i<@dblinks;$i )
{
$dblink_clist->set_text($i,0,$dblinks[$i]->primary_id);
$dblink_clist->set_text($i,1,$dblinks[$i]->database);
}
# redraw text widgets
foreach (@dblink_entry) { $_->set_text(""); }
if (@dblinks)
{
$dblink_entry[0]->set_text($dblinks[$current_dblink]->primary_id);
$dblink_entry[1]->set_text($dblinks[$current_dblink]->optional_id);
$dblink_entry[2]->set_text($dblinks[$current_dblink]->database);
$dblink_entry[3]->set_text($dblinks[$current_dblink]->comment);
}
$dblink_clist->moveto($current_dblink,0,0.3,0.0)
if ($dblink_clist->row_is_visible($current_dblink) ne 'full');
$dblink_clist->signal_handler_block($dblink_handler_id);
$dblink_clist->select_row($current_dblink,0);
$dblink_clist->signal_handler_unblock($dblink_handler_id);
Gtk::CList::set_focus_row($dblink_clist,$current_dblink);
$dblink_clist->thaw();
}
sub init_reference_window
{
$current_ref = 0;
$ref_window = new Gtk::Dialog();
$ref_window->set_default_size(620,500);
$ref_window->set_policy($true,$true,$false);
$ref_window->set_title("References");
$ref_window->border_width(5);
# Create a scrolled window to pack the CList widget into
my $scrolled_window = new Gtk::ScrolledWindow( undef, undef );
$ref_window->vbox->pack_start( $scrolled_window, $true, $true, 0 );
$scrolled_window->set_policy( 'automatic', 'always' );
# Create the CList. For this example we use 2 columns
$ref_clist = new_with_titles Gtk::CList( "Medline","Title","Authors" );
# When a selection is made, we want to know about it. The callback
# used is selection_made, and its code can be found further down
$ref_handler_id = $ref_clist->signal_connect( "select_row",
sub{ return if (!defined($seq[$current]));
my ( $clist, $row ) = @_;
&store_current_reference;
$current_ref = $row;
&update_reference_window;
} );
# It isn't necessary to shadow the border, but it looks nice :)
$ref_clist->set_shadow_type( 'out' );
# What however is important, is that we set the column widths as
# they will never be right otherwise. Note that the columns are
# numbered from 0 and up (to 1 in this case).
$ref_clist->set_column_width( 0, 70 );
$ref_clist->set_column_width( 1, 350 );
$ref_clist->set_column_width( 2, 300 );
# Add the CList widget to the vertical box
$scrolled_window->add( $ref_clist );
my $bbox = new Gtk::HBox( $false, 5 );
$bbox->border_width(10);
my $arrow = new Gtk::Arrow('down','out');
my $button = new Gtk::Button();
$button->add($arrow);
$bbox->pack_end( $button, $false, $false, 0);
$button->signal_connect
( "clicked",
# next ref button handler
sub { return if (!defined($seq[$current]));
&store_current_reference;
$current_ref
if ($current_ref <((scalar $seq[$current]->annotation->each_Reference)-1));
&update_reference_window;
} );
$arrow = new Gtk::Arrow('up','out');
$button = new Gtk::Button();
$button->add($arrow);
$bbox->pack_end( $button, $false, $false, 0);
$button->signal_connect( "clicked",
# prev comment button handler
sub { return if (!defined($seq[$current]));
&store_current_reference;
$current_ref--
if ($current_ref > 0);
&update_reference_window;
} );
$button = new Gtk::Button("Add");
$bbox->pack_start( $button, $false, $false, 0);
$button->signal_connect( "clicked",
# add comment button handler
sub { return if (!defined($seq[$current]));
&store_current_reference;
my $ref = new Bio::Annotation::Reference;
$ref->medline("<New>");
$seq[$current]->annotation->add_Reference( $ref );
$ref_clist->append("","","");
$current_ref = ($seq[$current]->annotation->each_Reference)-1;
&update_reference_window;
} );
$button = new Gtk::Button("Delete");
$bbox->pack_start( $button, $false, $false, 0);
$button->signal_connect( "clicked",
# delete comment button handler
sub { return if !defined($seq[$current]);
$seq[$current]->annotation->remove_Reference( $current_ref );
$ref_clist->remove($current_ref);
$current_ref-- if ($current_ref > 0);
&update_reference_window;
} );
$ref_window->vbox->pack_start( $bbox, $false, $false, 0);
# horizontal box containing primary_id & optional_id entries
my $hbox;
$hbox = new Gtk::HBox( $true, 10 );
$hbox->border_width( 1 );
# text entries
$ref_entry[0] = new Gtk::Entry();
my $frame = new Gtk::Frame("Title");
$frame->add($ref_entry[0]);
$ref_window->vbox->pack_start( $frame, $false, $false, 5);
$ref_entry[1] = new Gtk::Entry();
$frame = new Gtk::Frame("Authors");
$frame->add($ref_entry[1]);
$ref_window->vbox->pack_start( $frame, $false, $false, 5);
# horizontal box
$hbox = new Gtk::HBox( $true, 10 );
$hbox->border_width( 1 );
# text entries
$ref_entry[2] = new Gtk::Entry();
$frame = new Gtk::Frame("Comment");
$frame->add($ref_entry[2]);
$hbox->pack_start( $frame, $true, $true, 0);
$ref_entry[3] = new Gtk::Entry();
$frame = new Gtk::Frame("Location");
$frame->add($ref_entry[3]);
$hbox->pack_end( $frame, $true, $true, 0);
$ref_window->vbox->pack_start( $hbox, $false, $false, 5);
# horizontal box
$hbox = new Gtk::HBox( $false, 10 );
$hbox->border_width( 1 );
# text entries
$ref_entry[4] = new Gtk::Entry();
$frame = new Gtk::Frame("Medline");
$frame->add($ref_entry[4]);
$hbox->pack_start( $frame, $false, $false, 0);
# $ref_entry[5] = new Gtk::Entry();
# $frame = new Gtk::Frame("Start");
# $frame->add($ref_entry[5]);
# $hbox->pack_start( $frame, $false, $false, 0);
$ref_entry[5] = new Gtk::Entry();
$frame = new Gtk::Frame("Reference Position");
$frame->add($ref_entry[5]);
$hbox->pack_end( $frame, $true, $true, 0);
$ref_window->vbox->pack_start( $hbox, $false, $false, 5);
$bbox = new Gtk::HButtonBox();
$bbox->set_layout("end");
$button = new Gtk::Button( "Close" );
$bbox->add( $button );
$button->signal_connect("clicked",
# close button handler
sub{ $ref_window->hide();
&store_current_reference;
});
$ref_window->action_area->pack_start( $bbox, $true, $true, 0 );
$ref_window->signal_connect_after( "delete_event",
# window delete handler
sub{ $ref_window->hide();
&store_current_reference;
return &Gtk::true;
});
}
sub store_current_reference
{
if ((defined($seq[$current])) && ($seq[$current]->annotation->each_Reference))
{
(($seq[$current]->annotation->each_Reference)[$current_ref])->
title($ref_entry[0]->get_chars(0,-1) );
(($seq[$current]->annotation->each_Reference)[$current_ref])->
authors($ref_entry[1]->get_chars(0,-1) );
(($seq[$current]->annotation->each_Reference)[$current_ref])->
comment($ref_entry[2]->get_chars(0,-1) );
(($seq[$current]->annotation->each_Reference)[$current_ref])->
location($ref_entry[3]->get_chars(0,-1) );
(($seq[$current]->annotation->each_Reference)[$current_ref])->
medline($ref_entry[4]->get_chars(0,-1) );
# (($seq[$current]->annotation->each_Reference)[$current_ref])->
# start($ref_entry[5]->get_chars(0,-1) );
(($seq[$current]->annotation->each_Reference)[$current_ref])->
rp($ref_entry[5]->get_chars(0,-1) );
}
}
sub update_reference_window
{
my ($show_me) = @_;
$ref_window->show_all() if (defined($show_me));
$ref_clist->freeze();
if (!defined($seq[$current]))
{
$ref_clist->clear();
$ref_clist->thaw();
foreach (@ref_entry) { $_->set_text(""); }
return;
}
my @refs = $seq[$current]->annotation->each_Reference;
# reset clist if rows are different to references
if ($ref_clist->rows != @refs) {
$ref_clist->clear();
foreach (@refs) { $ref_clist->append("","",""); }
}
# redraw references
for(my $i=0;$i<@refs;$i )
{
$ref_clist->set_text($i,0,$refs[$i]->medline)
if ($refs[$i]->medline);
$ref_clist->set_text($i,1,$refs[$i]->title)
if ($refs[$i]->title);
$ref_clist->set_text($i,2,$refs[$i]->authors)
if ($refs[$i]->authors);
}
# redraw text widgets
foreach (@ref_entry) { $_->set_text(""); }
if (@refs) {
$ref_entry[0]->set_text($refs[$current_ref]->title);
$ref_entry[1]->set_text($refs[$current_ref]->authors);
$ref_entry[2]->set_text($refs[$current_ref]->comment);
$ref_entry[3]->set_text($refs[$current_ref]->location);
$ref_entry[4]->set_text($refs[$current_ref]->medline);
# $ref_entry[5]->set_text($refs[$current_ref]->start);
$ref_entry[5]->set_text($refs[$current_ref]->rp);
}
$ref_clist->moveto($current_ref,0,0.3,0.0)
if ($ref_clist->row_is_visible($current_ref) ne 'full');
$ref_clist->signal_handler_block($ref_handler_id);
$ref_clist->select_row($current_ref,0);
$ref_clist->signal_handler_unblock($ref_handler_id);
Gtk::CList::set_focus_row($ref_clist,$current_ref);
$ref_clist->thaw();
}
sub init_about_dialog {
my ($window,$bg,$tbox,$vbox,$hbox,$sep,$butbox,$button,$pixmap);
$about_dialog = new Gtk::Window("dialog");
$about_dialog->set_title("About gSequence");
$about_dialog->signal_connect_after("destroy" =>
sub { $about_dialog->hide;
return &Gtk::true; });
$about_dialog->set_default_size('350','350');
$about_dialog->set_policy(1,1,0);
$window = $about_dialog->window;
$bg = $about_dialog->style->bg('normal');
$vbox= new Gtk::VBox(0,0);
$about_dialog->add($vbox);
$tbox = new Gtk::Label("\ngSequence\nAuthor: Lorenz Pollak\n\n
gSequence is cool! :-)\n(this text is to be written...)
\n");
$vbox->pack_start($tbox,1,1,1);
$hbox = new Gtk::HBox(0,0);
$vbox->pack_start($hbox,0,0,0);
$sep = new Gtk::HSeparator;
$sep->set_usize(-1,5);
$vbox->pack_start($sep,0,1,0);
$butbox = new Gtk::HButtonBox;
$butbox->set_usize(-1,32);
$vbox->pack_start($butbox, 0,1,0);
$button = new_with_label Gtk::Button("OK");
$button->set_usize(50,-1);
$button->signal_connect('clicked', sub { $about_dialog->hide; });
$button->can_default(1);
$button->grab_default;
$butbox->add($button);
return 1;
}
sub init_feature_window
{
$current_feature_item = 0;
$feature_window = new Gtk::Dialog();
$feature_window->set_default_size(500,400);
$feature_window->set_policy($true,$true,$false);
$feature_window->set_title("Sequence Features");
$feature_window->border_width(5);
my $pane = new Gtk::HPaned();
$feature_window->vbox->pack_start( $pane, $true, $true, 0);
$pane->set_handle_size( 10 );
$pane->set_gutter_size( 8 );
# Create a VBox for the Entry and Tree Scrolled Window
my $vbox = new Gtk::VBox( $false, 0 );
$pane->add1( $vbox );
# Create a ScrolledWindow for the tree
my $tree_scrolled_win = new Gtk::ScrolledWindow( undef, undef );
$tree_scrolled_win->set_usize( 150, 400 );
$vbox->pack_start( $tree_scrolled_win, $true, $true, 0 );
$tree_scrolled_win->set_policy( 'automatic', 'automatic' );
#my $list_scrolled_win = new Gtk::ScrolledWindow( undef, undef );
#$list_scrolled_win->set_policy( 'automatic', 'automatic' );
$vbox = new Gtk::VBox( $false, 0 );
$pane->add2( $vbox );
# add stuff to the vbox
# text entries
my $hbox = new Gtk::HBox( $true, 10 );
$feature_entry[0] = new Gtk::Entry();
my $frame = new Gtk::Frame("Primary Tag");
$frame->add($feature_entry[0]);
$hbox->pack_start( $frame, $true, $true, 0);
$feature_entry[1] = new Gtk::Entry();
$frame = new Gtk::Frame("Source Tag");
$frame->add($feature_entry[1]);
$hbox->pack_end( $frame, $true, $true, 0);
$vbox->pack_start( $hbox, $false, $false, 5);
$hbox = new Gtk::HBox( $true, 10 );
my $adj = new Gtk::Adjustment( 0, 0, 0, 0, 0, 0 );
$feature_spinner[0] = new Gtk::SpinButton( $adj, 0.0, 0 );
$feature_spinner[0]->signal_connect( "changed", \&select_feature_region);
$frame = new Gtk::Frame("Start");
$frame->add($feature_spinner[0]);
$hbox->pack_start( $frame, $true, $true, 0);
$adj = new Gtk::Adjustment( 0, 0, 0, 0, 0, 0 );
$feature_spinner[1] = new Gtk::SpinButton( $adj, 0.0, 0 );
$feature_spinner[1]->signal_connect( "changed", \&select_feature_region);
$frame = new Gtk::Frame("End");
$frame->add($feature_spinner[1]);
$hbox->pack_start( $frame, $true, $true, 0);
$frame = new Gtk::Frame("Strand");
$hbox->pack_start( $frame, $true, $true, 0);
$frame = new Gtk::Frame("Score");
$hbox->pack_start( $frame, $true, $true, 0);
$vbox->pack_start( $hbox, $false, $false, 5);
$feature_entry[2] = new Gtk::Entry();
$frame = new Gtk::Frame("Description");
$frame->add($feature_entry[2]);
$vbox->pack_start( $frame, $false, $false, 5);
my $bbox = new Gtk::HBox( $false, 5 );
$bbox->border_width(10);
my $button = new Gtk::Button("Add");
$bbox->pack_start( $button, $false, $false, 0);
$button->signal_connect( "clicked",
# add comment button handler
sub { return if (!defined($seq[$current]));
&store_current_feature if ($current_feature_item);
my $feature = new Bio::SeqFeature::Generic;
$feature->primary_tag("<New>");
$seq[$current]->add_SeqFeature( $feature );
my $item_new = new_with_label Gtk::TreeItem( "<New>" );
$item_new->set_user_data( $feature );
$item_new->signal_connect( 'select', \&select_feature_item );
$current_feature_item->parent->append( $item_new )
if ($current_feature_item);
$feature_tree->append( $item_new ) if (!$current_feature_item);
$item_new->show();
$current_feature_item->deselect()
if ($current_feature_item);
$item_new->select();
} );
$button = new Gtk::Button("Add Subfeature");
$bbox->pack_start( $button, $false, $false, 0);
$button->signal_connect( "clicked",
# add comment button handler
sub { return if (!defined($seq[$current])||!$current_feature_item);
&store_current_feature;
my $feature = new Bio::SeqFeature::Generic;
$feature->primary_tag("<New>");
$feature->start($current_feature_item->get_user_data->start);
$feature->end($current_feature_item->get_user_data->end);
$current_feature_item->get_user_data->add_sub_SeqFeature( $feature );
my $new_subtree = new Gtk::Tree();
$current_feature_item->set_subtree( $new_subtree );
my $item_new = new_with_label Gtk::TreeItem( "<New>" );
$item_new->set_user_data( $feature );
$item_new->signal_connect( 'select', \&select_feature_item );
$new_subtree->append( $item_new );
$item_new->show();
$current_feature_item->deselect();
$current_feature_item->expand();
$item_new->select();
} );
$button = new Gtk::Button("Delete");
$bbox->pack_start( $button, $false, $false, 0);
$button->signal_connect( "clicked",
# delete comment button handler
sub { return if (!$current_feature_item);
&store_current_feature;
my $flist = $seq[$current]->{_as_feat};
my $pos;
for(my $i=0;$i<@$flist;$i ) {
$pos=$i if $$flist[$i]==$current_feature_item->get_user_data();
}
splice @$flist, $pos, 1;
$seq[$current]->{_as_feat} = $flist;
$current_feature_item->parent->remove_item($current_feature_item);
$current_feature_item=0;
} );
$vbox->pack_end( $bbox, $false, $false, 0);
# Create root tree
$feature_tree = new Gtk::Tree();
$tree_scrolled_win->add_with_viewport( $feature_tree );
$feature_tree->set_selection_mode( 'single' );
$feature_tree->set_view_mode( 'item' );
$bbox = new Gtk::HButtonBox();
$bbox->set_layout("end");
$button = new Gtk::Button( "Close" );
$bbox->add( $button );
$button->signal_connect("clicked",
# close button handler
sub{ $feature_window->hide();
&store_current_feature;
});
$feature_window->action_area->pack_start( $bbox, $true, $true, 0 );
$feature_window->signal_connect_after( "delete_event",
# window delete handler
sub{ $feature_window->hide();
&store_current_feature;
return &Gtk::true;
});
}
# Callback for expanding tree
sub expand_feature_tree
{
my ( $item, $subtree ) = @_;
my ($feature,$subfeature,$item_new,$new_subtree);
$feature = $item->get_user_data();
foreach $subfeature ($feature->sub_SeqFeature)
{
$item_new = new_with_label Gtk::TreeItem( $subfeature->primary_tag );
$item_new->set_user_data( $subfeature );
$item_new->signal_connect( 'select', \&select_feature_item );
$subtree->append( $item_new );
$item_new->show();
if ( $subfeature->sub_SeqFeature )
{
$new_subtree = new Gtk::Tree();
$item_new->set_subtree( $new_subtree );
$item_new->signal_connect( 'expand',
\&expand_feature_tree,
$new_subtree );
$item_new->signal_connect( 'collapse', \&collapse_feature_tree );
}
$item_new->expand();
}
}
# Callback for collapsing tree
sub collapse_feature_tree
{
my ( $item ) = @_;
my $subtree = new Gtk::Tree();
$item->remove_subtree();
$item->set_subtree( $subtree );
$item->signal_connect( 'expand', \&expand_feature_tree, $subtree );
}
sub store_current_feature
{
if ((defined($seq[$current])) && ($seq[$current]->top_SeqFeatures) && ($current_feature_item))
{
my $current_feature = $current_feature_item->get_user_data();
$current_feature->primary_tag( $feature_entry[0]->get_chars(0,-1) );
$current_feature->source_tag( $feature_entry[1]->get_chars(0,-1) );
if ($current_feature->has_tag("description"))
{
$current_feature->remove_tag("description");
$current_feature->add_tag_value("description",
$feature_entry[2]->get_chars(0,-1));
}
$current_feature->start($feature_spinner[0]->get_value_as_int());
$current_feature->end($feature_spinner[1]->get_value_as_int());
# set tree item
($current_feature_item->children)[0]->set($current_feature->primary_tag);
}
}
sub select_feature_item
{
my ($widget) = @_;
&store_current_feature;
$current_feature_item->deselect()
if $current_feature_item;
$current_feature_item = $widget;
&update_feature_paned2;
}
sub update_feature_paned2
{
$feature_entry[0]->set_text("");
$feature_entry[1]->set_text("");
$feature_entry[2]->set_text("");
return if (!defined($seq[$current])||(!$current_feature_item));
my $current_feature = $current_feature_item->get_user_data();
$feature_entry[0]->set_text($current_feature->primary_tag);
$feature_entry[1]->set_text($current_feature->source_tag)
if (defined($current_feature->source_tag));
$feature_entry[2]->set_text(($current_feature->each_tag_value("description"))[0])
if ($current_feature->has_tag("description"));
my $adj = new Gtk::Adjustment($current_feature->start,
0,
$seq[$current]->length-1,
1,
1,
0
);
$feature_spinner[0]->set_adjustment($adj);
$feature_spinner[0]->set_value($current_feature->start);
$feature_spinner[0]->show_all();
$adj = new Gtk::Adjustment($current_feature->end,
0,
$seq[$current]->length-1,
1,
1,
0
);
$feature_spinner[1]->set_adjustment($adj);
$feature_spinner[1]->set_value($current_feature->end);
$feature_spinner[1]->show_all();
}
sub select_feature_region
{
$seq_edit[$current]->freeze;
$seq_edit[$current]->select_region($feature_spinner[0]->get_value_as_int(),
$feature_spinner[1]->get_value_as_int() 1);
$seq_edit[$current]->thaw;
}
sub update_feature_window
{
my ($show_me) = @_;
$feature_window->show_all() if (defined($show_me));
$feature_tree->clear_items(0,-1);
if (!defined($seq[$current]))
{
&update_feature_paned2;
return;
}
my ($item_new,$new_subtree);
foreach ($seq[$current]->top_SeqFeatures)
{
$item_new = new_with_label Gtk::TreeItem( $_->primary_tag );
$item_new->set_user_data( $_ );
$item_new->signal_connect( 'select', \&select_feature_item );
$feature_tree->append( $item_new );
if ( $_->sub_SeqFeature )
{
$new_subtree = new Gtk::Tree();
$item_new->set_subtree( $new_subtree );
$item_new->signal_connect( 'expand',
\&expand_feature_tree,
$new_subtree );
$item_new->signal_connect( 'collapse', \&collapse_feature_tree );
}
$item_new->expand();
}
$feature_tree->select_item($current_feature_item)
if $current_feature_item;
$feature_tree->show_all();
&update_feature_paned2;
}
sub store_prefs
{
}
sub update_pref_window
{
$pref_window->show_all();
}
sub init_pref_window
{
$pref_window = new Gtk::Dialog();
$pref_window->set_default_size(500,400);
$pref_window->set_policy($true,$true,$false);
$pref_window->border_width( 5 );
# Create a new notebook, place the position of the tabs
my $notebook = new Gtk::Notebook();
$pref_window->vbox->pack_start( $notebook, $true, $true, 0);
$notebook->set_tab_pos( 'top' );
my $main_vbox = new Gtk::VBox($false,10);
my $label = new Gtk::Label( "Import Options" );
my $frame = new Gtk::Frame("Flat File Indexes");
my $vbox = new Gtk::VBox($false,10);
$frame->add($vbox);
$main_vbox->pack_start($frame,$false,$false,10);
$notebook->append_page( $main_vbox, $label );
my $hbox = new Gtk::HBox($false,0);
$pref_entry[0] = new Gtk::Entry();
$frame = new Gtk::Frame("Indexes Directory");
$frame->add($pref_entry[0]);
$hbox->pack_start( $frame, $true, $false, 0);
$pref_entry[1] = new Gtk::Entry();
$frame = new Gtk::Frame("Index Type");
$frame->add($pref_entry[1]);
$hbox->pack_start( $frame, $false, $false, 0);
$vbox->pack_start( $hbox, $false, $false, 0);
$pref_entry[2] = new Gtk::Entry();
$frame = new Gtk::Frame("Fasta Index Name");
$frame->add($pref_entry[2]);
$vbox->pack_start( $frame, $false, $false, 0);
$pref_entry[3] = new Gtk::Entry();
$frame = new Gtk::Frame("SwissProt Index Name");
$frame->add($pref_entry[3]);
$vbox->pack_start( $frame, $false, $false, 0);
$pref_entry[4] = new Gtk::Entry();
$frame = new Gtk::Frame("SwissPfam Index Name");
$frame->add($pref_entry[4]);
$vbox->pack_start( $frame, $false, $false, 0);
$frame = new Gtk::Frame("Remote DBs");
$hbox = new Gtk::HBox($false,10);
$frame->add($hbox);
$main_vbox->pack_start($frame,$false,$false,10);
$pref_entry[5] = new Gtk::Entry();
$frame = new Gtk::Frame("AceDB host");
$frame->add($pref_entry[5]);
$hbox->pack_start( $frame, $true, $false, 0);
$pref_entry[6] = new Gtk::Entry();
$frame = new Gtk::Frame("AceDB port");
$frame->add($pref_entry[6]);
$hbox->pack_start( $frame, $false, $false, 0);
$notebook->set_page( 0 );
my $bbox = new Gtk::HButtonBox();
$bbox->set_layout("end");
my $button = new Gtk::Button( "Save" );
$bbox->add( $button );
$button->signal_connect("clicked",
# close button handler
sub{ $pref_window->hide();
&store_prefs();
});
$button = new Gtk::Button( "Close" );
$bbox->add( $button );
$button->signal_connect("clicked",
# close button handler
sub{ $pref_window->hide();
});
$pref_window->action_area->pack_start( $bbox, $true, $true, 0 );
$pref_window->signal_connect_after( "delete_event",
# window delete handler
sub{ $pref_window->hide();
return &Gtk::true;
});
}