1#!/usr/local/bin/perl 2# gSequence - Protein Sequence Control Panel 3# by Lorenz Pollsk 4# 5# this is work in progress! use this only for testing 6 7use Gtk; 8use strict; 9use Bio::Seq; 10use Bio::SeqIO; 11use Bio::Tools::SeqStats; 12use Bio::SeqFeature::Generic; 13use Bio::Index::Abstract; 14use Bio::DB::GenBank; 15use Bio::DB::GenPept; 16 17init Gtk; 18 19# constant 20my $false = 0; 21my $true = 1; 22 23# global widgets 24my ($main_notebook,@main_label,@seq_edit); 25my $about_dialog; 26my ($import_dialog,$import_entry,@import_buttons,$import_from); 27my ($description_window,$description_edit); 28my ($comment_window,$comment_edit,$current_comment,$comment_frame); 29my ($seqstats_window,$seqstats_edit); 30my ($dblink_window,@dblink_entry,$current_dblink,$dblink_clist,$dblink_handler_id); 31my ($ref_window,@ref_entry,$current_ref,$ref_clist,$ref_handler_id); 32my ($feature_window,@feature_entry,$current_feature_item,@feature_spinner, 33 $feature_handler_id,$feature_tree); 34my ($pref_window,@pref_entry); 35 36# global file data 37my @seq; 38my @filename; 39my @modified; 40my @locked; # locked sequence for editing ? 41my $current; 42 43# menu 44my @menu_items = ( { path => '/_File', 45 type => '<Branch>' }, 46 { path => '/File/_New', 47 accelerator => '<control>N', 48 callback => \&new }, 49 { path => '/File/_Open SwissProt', 50 accelerator => '<control>O', 51 callback => \&open_dialog }, 52 { path => '/File/_Save SwissProt', 53 accelerator => '<control>S', 54 callback => \&save }, 55 { path => '/File/Save _As...', 56 callback => \&saveas_dialog }, 57 { path => '/File/Close', 58 callback => \&close }, 59 { path => '/File/sep1', 60 type => '<Separator>' }, 61 { path => '/File/_Import from...', 62 type => '<Branch>' }, 63 { path => '/File/Import from.../Remote DB', 64 type => '<Branch>' }, 65 { path => '/File/Import from.../Remote DB/AceDB', 66 callback => sub { &seq_import("ace"); } }, 67 { path => '/File/Import from.../Remote DB/GenPept', 68 callback => sub { &seq_import("genpept"); } }, 69 { path => '/File/Import from.../Flat File Index', 70 type => '<Branch>' }, 71 { path => '/File/Import from.../Flat File Index/Fasta', 72 callback => sub { &seq_import("fasta"); } }, 73 { path => '/File/Import from.../Flat File Index/SwissProt', 74 callback => sub { &seq_import("swissprot"); } }, 75 { path => '/File/Import from.../Flat File Index/SwissPfam', 76 callback => sub { &seq_import("swisspfam"); } }, 77 { path => '/File/_Export to...' }, 78 { path => '/File/sep2', 79 type => '<Separator>' }, 80 { path => '/File/_Quit', 81 callback => sub { Gtk->exit( 0 ); } }, 82 83 { path => '/_Edit', 84 type => '<Branch>' }, 85 { path => '/Edit/C_ut', 86 callback => sub { $seq_edit[$current]->cut_clipboard(); }, 87 accelerator => '<control>X' }, 88 { path => '/Edit/_Copy', 89 callback => sub { $seq_edit[$current]->copy_clipboard(); }, 90 accelerator => '<control>C' }, 91 { path => '/Edit/_Paste', 92 callback => sub { $seq_edit[$current]->paste_clipboard(); }, 93 accelerator => '<control>V' }, 94 { path => '/Edit/Select All', 95 callback => sub { $seq_edit[$current]->select_region(0,-1); } }, 96 97 { path => '/_Specs', 98 type => '<Branch>' }, 99 { path => '/Specs/_Sequence Stats', 100 callback => sub {&update_seqstats_window(1);} }, 101 { path => '/Specs/sep1', 102 type => '<Separator>' }, 103 { path => '/Specs/_Description', 104 callback => sub {&update_description_window(1);} }, 105 { path => '/Specs/_Comments', 106 callback => sub {&update_comment_window(1);} }, 107 { path => '/Specs/_DB Links', 108 callback => sub {&update_dblink_window(1);} }, 109 { path => '/Specs/_References', 110 callback => sub {&update_reference_window(1);} }, 111 { path => '/Specs/sep2', 112 type => '<Separator>' }, 113 { path => '/Specs/_Features', 114 callback => sub {&update_feature_window(1);} }, 115 116 { path => '/_Tools', 117 type => '<Branch>' }, 118 { path => '/Tools/Code Table' }, 119 { path => '/Tools/sep1', 120 type => '<Separator>' }, 121 { path => '/Tools/local Blast' }, 122 { path => '/Tools/local HMMER' }, 123 { path => '/Tools/hmmpfam' }, 124 { path => '/Tools/web Blast' }, 125 126 { path => '/_Options', 127 type => '<Branch>' }, 128 { path => '/Options/_Preferences', 129 callback => sub {&update_pref_window(1);} }, 130 131 { path => '/_Help', 132 type => '<LastBranch>' }, 133 { path => '/Help/Help' }, 134 { path => '/Help/_About...', 135 callback => sub { $about_dialog->show_all();} } ); 136 137### main 138 139$current = 0; 140&init_windows(); 141main Gtk; 142exit( 0 ); 143 144 145### Subroutines 146 147sub init_windows 148{ 149 &init_main_window(); 150 &init_about_dialog(); 151 &init_import_dialog(); 152 &init_seqstats_window(); 153 &init_description_window(); 154 &init_comment_window(); 155 &init_dblink_window(); 156 &init_reference_window(); 157 &init_feature_window(); 158 &init_pref_window(); 159} 160 161sub init_main_window 162{ 163 # toplevel window 164 my $window; 165 $window = new Gtk::Window( 'toplevel' ); 166 $window->signal_connect( 'destroy', sub { Gtk->exit( 0 ); } ); 167 $window->set_title( "gSequence" ); 168 $window->set_usize( 600, 400 ); 169 170 # vertical box containing menu and text editor widget 171 my $main_vbox; 172 $main_vbox = new Gtk::VBox( $false, 1 ); 173 $main_vbox->border_width( 1 ); 174 $window->add( $main_vbox ); 175 176 # handlebox for menubar 177 my $handlebox; 178 $handlebox = new Gtk::HandleBox(); 179 $main_vbox->pack_start( $handlebox, $false, $true, 0 ); 180 181 # menubar 182 my $menubar; 183 $menubar = get_menu( $window ); 184 $handlebox->add( $menubar ); 185 186 # text widget 187 $seq_edit[$current] = new Gtk::Text( undef, undef ); 188 $seq_edit[$current]->set_editable( $true ); 189 190 # vertical scrollbar for text widget 191 my $scrollbar; 192 $scrollbar = new Gtk::VScrollbar( $seq_edit[$current]->vadj ); 193 194 # horizontal box containing text widget and scrollbar 195 my $seq_edit_hbox; 196 $seq_edit_hbox = new Gtk::HBox( $false, 1 ); 197 $seq_edit_hbox->border_width( 1 ); 198 $seq_edit_hbox->pack_start( $seq_edit[$current], $true, $true, 0); 199 $seq_edit_hbox->pack_end( $scrollbar, $false, $true, 0); 200 201 $main_notebook = new Gtk::Notebook(); 202 $main_notebook->set_tab_pos( 'top' ); 203 204 $main_vbox->pack_end( $main_notebook, $true, $true, 0); 205 206 # show everything 207 $window->show_all(); 208 209 $main_notebook->signal_connect_after("switch-page", 210 sub{ #$seq[$current]->seq($seq_edit[$current]->get_chars(0,-1)) 211 # if (defined($seq[$current])); 212 $current = $main_notebook->get_current_page(); 213 &update_seq_data(); } ); 214} 215 216sub get_menu 217{ 218 my ( $window ) = @_; 219 220 my $menubar; 221 my $item_factory; 222 my $accel_group; 223 224 $accel_group = new Gtk::AccelGroup(); 225 226 # This function initializes the item factory. 227 # Param 1: The type of menu - can be 'Gtk::MenuBar', 'Gtk::Menu', 228 # or 'Gtk::OptionMenu'. 229 # Param 2: The path of the menu. 230 # Param 3: The accelerator group. The item factory sets up 231 # the accelerator table while generating menus. 232 $item_factory = new Gtk::ItemFactory( 'Gtk::MenuBar', 233 '<main>', 234 $accel_group ); 235 236 # This function generates the menu items. Pass the item factory, 237 # the number of items in the array, the array itself, and any 238 # callback data for the the menu items. 239 $item_factory->create_items( @menu_items ); 240 241 # Attach the new accelerator group to the window. 242 $window->add_accel_group( $accel_group ); 243 244 # Finally, return the actual menu bar created by the item factory. 245 #*menubar = gtk_item_factory_get_widget (item_factory, "<main>"); 246 return ( $item_factory->get_widget( '<main>' ) ); 247} 248 249sub new_seq_page 250{ 251 my ($seq) = shift; 252 my $curr; 253 254 push @seq,$seq; 255 $curr = @seq - 1; 256 $main_label[$curr] = new Gtk::Label($seq[$curr]->id()) 257 if (defined($seq[$curr])); 258 $main_label[$curr] = new Gtk::Label("<New>") 259 if (!defined($seq[$curr])); 260 261 # text widget 262 $seq_edit[$curr] = new Gtk::Text( undef, undef ); 263 $seq_edit[$curr]->set_editable( $true ); 264 265 # vertical scrollbar for text widget 266 my $scrollbar; 267 $scrollbar = new Gtk::VScrollbar( $seq_edit[$curr]->vadj ); 268 269 # horizontal box containing text widget and scrollbar 270 my $seq_edit_hbox; 271 $seq_edit_hbox = new Gtk::HBox( $false, 1 ); 272 $seq_edit_hbox->border_width( 1 ); 273 $seq_edit_hbox->pack_start( $seq_edit[$curr], $true, $true, 0); 274 $seq_edit_hbox->pack_end( $scrollbar, $false, $true, 0); 275 276 $main_notebook->append_page( $seq_edit_hbox, $main_label[$curr] ); 277 $main_notebook->show_all(); 278 $main_notebook->set_page(-1); 279} 280 281sub seq_fetch 282{ 283 my ($server,$port,$dir,$db); # read from preferences 284 my ($dbobj); 285 286 return if (!defined($import_from) || !($import_from)); 287 288 $dbobj = Bio::DB::GenPept->new() if ($import_from eq "genpept"); 289 $dbobj = Bio::DB::Ace->new(-host=>$server,-port=>$port) 290 if ($import_from eq "ace"); 291 $dbobj = Bio::Index::Abstract->new("$dir/$db") 292 if ($import_from eq "fasta") || 293 ($import_from eq "swissprot") || 294 ($import_from eq "swisspfam"); 295 296 if( $import_buttons[0]->get_active() ) { 297 &new_seq_page($dbobj->get_Seq_by_id($import_entry->get_text())); 298 } else { 299 &new_seq_page($dbobj->get_Seq_by_acc($import_entry->get_text())); 300 } 301} 302 303sub seq_import 304{ 305 ($import_from) = @_; 306 my %names = ( "ace" => "AceDB", 307 "genpept" => "GenPept DB", 308 "fasta" => "Fasta Flat File", 309 "swissprot" => "SwissProt Flat File", 310 "swisspfam" => "SwissPfam Flat File" 311 ); 312 $import_dialog->set_title("Import from ".$names{$import_from}); 313 $import_entry->set_text(""); 314 $import_dialog->show_all(); 315} 316 317sub init_import_dialog 318{ 319 $import_dialog = new Gtk::Dialog(); 320 $import_dialog->border_width(5); 321 322 # create the first button and add it to a box 323 my $button = new Gtk::RadioButton( "Fetch by ID" ); 324 $import_dialog->vbox->pack_start($button,$false,$false,2); 325 326 # create the second button and add it to a box 327 $button = new Gtk::RadioButton( "Fetch by ACCESSION", $button ); 328 $import_dialog->vbox->pack_start($button,$false,$false,2); 329 @import_buttons = $button->group(); 330 331 $import_entry = new Gtk::Entry(); 332 my $frame = new Gtk::Frame("Enter here:"); 333 $frame->add($import_entry); 334 $import_dialog->vbox->pack_start( $frame, $true, $true, 5); 335 336 my $bbox = new Gtk::HButtonBox(); 337 $bbox->set_layout("end"); 338 339 $button = new Gtk::Button( "OK" ); 340 $bbox->add( $button ); 341 $button->signal_connect("clicked", 342 # OK button handler 343 sub{ $import_dialog->hide(); 344 &seq_fetch(); 345 }); 346 347 $button = new Gtk::Button( "Cancel" ); 348 $bbox->add( $button ); 349 $button->signal_connect("clicked", 350 # close button handler 351 sub{ $import_dialog->hide(); 352 }); 353 354 $import_dialog->action_area->pack_start( $bbox, $true, $true, 0 ); 355 356 $import_dialog->signal_connect_after( "delete_event", 357 # window delete handler 358 sub{ $import_dialog->hide(); 359 return &Gtk::true; 360 }); 361} 362 363sub open_dialog 364{ 365 # Create a new file selection widget 366 my $open_dialog = new Gtk::FileSelection( "Open File..." ); 367 # Connect the ok_button to open_ok_sel function 368 $open_dialog->ok_button->signal_connect( "clicked", 369 \&ok_open_dialog, 370 $open_dialog ); 371 # Connect the cancel_button to destroy the widget 372 $open_dialog->cancel_button->signal_connect( "clicked", 373 sub { $open_dialog->destroy(); } ); 374 $open_dialog->show(); 375} 376 377# Get the selected filename 378sub ok_open_dialog 379 { 380 my ( $widget, $file_selection ) = @_; 381 push @filename, $file_selection->get_filename(); 382 383 $widget->parent->parent->parent->destroy(); 384 385 my $in = Bio::SeqIO->new(-file => $filename[-1] , '-format' => 'swiss'); 386 387 &new_seq_page($in->next_seq()); 388} 389 390sub update_seq_data 391{ 392 $main_label[$current]->set_text($seq[$current]->id) if (defined($seq[$current])); 393 $main_label[$current]->set_text("<New>") if (!defined($seq[$current])); 394 395 $seq_edit[$current]->freeze(); 396 $seq_edit[$current]->delete_text(0,-1); 397 $seq_edit[$current]->insert(undef,undef,undef,$seq[$current]->seq()) if (defined($seq[$current])); 398 $seq_edit[$current]->thaw(); 399 400 &update_comment_window(); 401 &update_description_window(); 402 &update_seqstats_window(); 403 &update_dblink_window(); 404 &update_reference_window(); 405 &update_feature_window(); 406} 407 408sub new 409{ 410 &new_seq_page(undef); 411} 412 413sub close 414{ 415} 416 417sub save 418{ 419 if (!defined($filename[$current])||!$filename[$current]) 420 { 421 &saveas_dialog; 422 return; 423 } 424 my $out = Bio::SeqIO->new(-file => ">$filename[$current]" , '-format' => 'swiss'); 425 $out->write_seq($seq[$current]); 426} 427 428sub saveas_dialog 429{ 430 # Create a new file selection widget 431 my $saveas_dialog = new Gtk::FileSelection( "Save As..." ); 432 # Connect the ok_button to saveas_ok_sel function 433 $saveas_dialog->ok_button->signal_connect( "clicked", 434 \&ok_saveas_dialog, 435 $saveas_dialog ); 436 # Connect the cancel_button to destroy the widget 437 $saveas_dialog->cancel_button->signal_connect( "clicked", 438 sub { $saveas_dialog->destroy(); } ); 439 $saveas_dialog->show(); 440} 441 442# Get the selected filename and print it to the console 443sub ok_saveas_dialog 444 { 445 my ( $widget, $file_selection ) = @_; 446 my $filename = $file_selection->get_filename(); 447 $widget->parent->parent->parent->destroy(); 448 $filename[$current] = $filename; 449 my $out = Bio::SeqIO->new(-file => ">$filename[$current]" , '-format' => 'swiss'); 450 $out->write_seq($seq[$current]); 451 } 452 453sub init_comment_window 454{ 455 $current_comment = 0; 456 457 $comment_window = new Gtk::Dialog(); 458 $comment_window->set_default_size(650,300); 459 $comment_window->set_policy($false,$true,$false); 460 $comment_window->set_title("Comments"); 461 $comment_window->border_width(5); 462 463 # frame 464 $comment_frame = new Gtk::Frame( "Comment[".$current_comment."]" ); 465 466 # text widget 467 $comment_edit = new Gtk::Text( undef, undef ); 468 $comment_edit->set_editable( $true ); 469 $comment_edit->set_word_wrap( $true ); 470 471 # vertical scrollbar for text widget 472 my $scrollbar; 473 $scrollbar = new Gtk::VScrollbar( $comment_edit->vadj ); 474 475 # horizontal box containing text widget and scrollbar 476 my $hbox; 477 $hbox = new Gtk::HBox( $false, 1 ); 478 $hbox->border_width( 1 ); 479 $hbox->pack_start( $comment_edit, $true, $true, 0); 480 $hbox->pack_end( $scrollbar, $false, $true, 0); 481 $comment_frame->add($hbox); 482 $comment_window->vbox->pack_start( $comment_frame, $true, $true, 5); 483 484 my $bbox = new Gtk::HBox( $false, 5 ); 485 $bbox->border_width(10); 486 my $arrow = new Gtk::Arrow('right','out'); 487 my $button = new Gtk::Button(); 488 $button->add($arrow); 489 $bbox->pack_end( $button, $false, $false, 0); 490 $button->signal_connect 491 ( "clicked", 492 # next comment button handler 493 sub { return if !defined($seq[$current]); 494 &store_current_comment; 495 $current_comment++ 496 if ($current_comment <((scalar $seq[$current]->annotation->each_Comment)-1)); 497 &update_comment_window; 498 } ); 499 500 $arrow = new Gtk::Arrow('left','out'); 501 $button = new Gtk::Button(); 502 $button->add($arrow); 503 $bbox->pack_end( $button, $false, $false, 0); 504 $button->signal_connect( "clicked", 505 # prev comment button handler 506 sub { return if !defined($seq[$current]); 507 &store_current_comment; 508 $current_comment-- 509 if ($current_comment > 0); 510 &update_comment_window; 511 } ); 512 513 $button = new Gtk::Button("Add"); 514 $bbox->pack_start( $button, $false, $false, 0); 515 $button->signal_connect( "clicked", 516 # add comment button handler 517 sub { return if !defined($seq[$current]); 518 &store_current_comment; 519 my $comment = new Bio::Annotation::Comment; 520 $comment->text(""); 521 $seq[$current]->annotation->add_Comment( $comment ); 522 $current_comment = $seq[$current]->annotation->each_Comment - 1; 523 &update_comment_window; 524 } ); 525 526 $button = new Gtk::Button("Delete"); 527 $bbox->pack_start( $button, $false, $false, 0); 528 $button->signal_connect( "clicked", 529 # delete comment button handler 530 sub { return if !defined($seq[$current]); 531 $seq[$current]->annotation->remove_Comment( $current_comment ); 532 $current_comment = $current_comment - 1 533 if ($current_comment > 0); 534 &update_comment_window; 535 } ); 536 537 $comment_window->vbox->pack_end( $bbox, $false, $false, 0); 538 539 $bbox = new Gtk::HButtonBox(); 540 $bbox->set_layout("end"); 541 542 $button = new Gtk::Button( "Close" ); 543 $bbox->add( $button ); 544 $button->signal_connect("clicked", 545 # close button handler 546 sub{ $comment_window->hide(); 547 &store_current_comment; 548 }); 549 550 $comment_window->action_area->pack_start( $bbox, $true, $true, 0 ); 551 $comment_window->signal_connect_after( "delete_event", 552 # window delete handler 553 sub{ $comment_window->hide(); 554 &store_current_comment; 555 return &Gtk::true; 556 }); 557} 558 559sub store_current_comment 560{ 561 (($seq[$current]->annotation->each_Comment)[$current_comment])-> 562 text($comment_edit->get_chars(0,-1) ) 563 if ((defined($seq[$current])) && ($seq[$current]->annotation->each_Comment)); 564} 565 566sub update_comment_window 567{ 568 my ($show_me) = @_; 569 $comment_frame->set_label("Comment[".$current_comment."]"); 570 # insert comment text 571 $comment_edit->freeze(); 572 $comment_edit->delete_text(0,-1); 573 if (defined($seq[$current])) 574 { 575 my @comment = $seq[$current]->annotation->each_Comment; 576 $comment_edit->insert(undef,undef,undef, $comment[$current_comment]->text) 577 if (@comment); 578 } 579 $comment_edit->thaw(); 580 581 $comment_window->show_all() if (defined($show_me)); 582} 583 584sub init_description_window 585{ 586 $description_window = new Gtk::Dialog(); 587 $description_window->set_default_size(620,250); 588 $description_window->border_width(5); 589 $description_window->set_title("Description"); 590 591 # frame 592 my $description_frame = new Gtk::Frame( "Description" ); 593 594 # text widget 595 $description_edit = new Gtk::Text( undef, undef ); 596 $description_edit->set_editable( $true ); 597 $description_edit->set_word_wrap( $true ); 598 599 # vertical scrollbar for text widget 600 my $scrollbar; 601 $scrollbar = new Gtk::VScrollbar( $description_edit->vadj ); 602 603 # horizontal box containing text widget and scrollbar 604 my $hbox; 605 $hbox = new Gtk::HBox( $false, 1 ); 606 $hbox->border_width( 1 ); 607 $hbox->pack_start( $description_edit, $true, $true, 0); 608 $hbox->pack_end( $scrollbar, $false, $true, 0); 609 $description_frame->add($hbox); 610 $description_window->vbox->pack_start( $description_frame, $true, $true, 5); 611 612 my $bbox = new Gtk::HButtonBox(); 613 $bbox->set_layout("end"); 614 615 my $button = new Gtk::Button( "Close" ); 616 $bbox->add( $button ); 617 $button->signal_connect("clicked", 618 # close button handler 619 sub{ $description_window->hide(); 620 $seq[$current]->desc($description_edit->get_chars(0,-1)) 621 if $description_edit->get_chars(0,-1); 622 }); 623 624 $description_window->action_area->pack_start( $bbox, $true, $true, 0 ); 625 $description_window->signal_connect_after( "delete_event", 626 # window delete handler 627 sub{ $description_window->hide(); 628 $seq[$current]->desc($description_edit->get_chars(0,-1)) 629 if $description_edit->get_chars(0,-1); 630 return &Gtk::true; 631 }); 632} 633 634sub update_description_window 635{ 636 my ($show_me) = @_; 637 $description_edit->freeze(); 638 $description_edit->delete_text(0,-1); 639 $description_edit->insert(undef,undef,undef,$seq[$current]->desc) 640 if defined($seq[$current]) && defined($seq[$current]->desc); 641 $description_edit->thaw(); 642 643 $description_window->show_all() if (defined($show_me)); 644} 645 646sub init_seqstats_window 647{ 648 $seqstats_window = new Gtk::Dialog(); 649 $seqstats_window->border_width(5); 650 $seqstats_window->set_default_size(100,250); 651 $seqstats_window->set_title("Sequence Statistics"); 652 653 # frame 654 my $seqstats_frame = new Gtk::Frame( "Sequence Statistics" ); 655 656 # text widget 657 $seqstats_edit = new Gtk::Text( undef, undef ); 658 $seqstats_edit->set_editable( $false ); 659 $seqstats_edit->set_word_wrap( $true ); 660 661 # vertical scrollbar for text widget 662 my $scrollbar; 663 $scrollbar = new Gtk::VScrollbar( $seqstats_edit->vadj ); 664 665 # horizontal box containing text widget and scrollbar 666 my $hbox; 667 $hbox = new Gtk::HBox( $false, 1 ); 668 $hbox->border_width( 1 ); 669 $hbox->pack_start( $seqstats_edit, $true, $true, 0); 670 $hbox->pack_end( $scrollbar, $false, $true, 0); 671 $seqstats_frame->add($hbox); 672 $seqstats_window->vbox->pack_start( $seqstats_frame, $true, $true, 5); 673 674 my $bbox = new Gtk::HButtonBox(); 675 $bbox->set_layout("end"); 676 677 my $button = new Gtk::Button( "Close" ); 678 $bbox->add( $button ); 679 $button->signal_connect("clicked", 680 # close button handler 681 sub{ $seqstats_window->hide(); 682 }); 683 684 $seqstats_window->action_area->pack_start( $bbox, $true, $true, 0 ); 685 $seqstats_window->signal_connect_after( "delete_event", 686 # window delete handler 687 sub{ $seqstats_window->hide(); 688 return &Gtk::true; 689 }); 690} 691 692sub update_seqstats_window 693{ 694 my ($show_me) = @_; 695 my ($data,$weight,$count_hash,$percent); 696 697 $seqstats_edit->freeze(); 698 $seqstats_edit->delete_text(0,-1); 699 if (defined($seq[$current])) 700 { 701 $data = $seq[$current]->id."\n\n"; 702 $weight = Bio::Tools::SeqStats->get_mol_wt($seq[$current]->primary_seq); 703 if ($$weight[0] == $$weight[1]) { 704 $data .= "Molecular weight of sequence equals to ".$$weight[0]."\n\n"; 705 } else { 706 $data .= "Molecular weight of sequence is greater than "; 707 $data .= $$weight[0]." and less than ".$$weight[1]."\n\n"; 708 } 709 $count_hash = Bio::Tools::SeqStats->count_monomers($seq[$current]->primary_seq); 710 $data .= "Amino Acids:\n"; 711 foreach (sort keys %$count_hash) 712 { 713 $percent = sprintf "%.1f", 714 (($$count_hash{$_} / $seq[$current]->length)*100); 715 $data .= "${_}: ".$$count_hash{$_}." (${percent}%) \n" 716 } 717 $seqstats_edit->insert(undef,undef,undef,$data) 718 } 719 $seqstats_edit->thaw(); 720 721 $seqstats_window->show_all() if (defined($show_me)); 722} 723 724sub init_dblink_window 725{ 726 $current_dblink = 0; 727 728 $dblink_window = new Gtk::Dialog(); 729 $dblink_window->set_default_size(500,400); 730 $dblink_window->set_policy($true,$true,$false); 731 $dblink_window->set_title("Database Links"); 732 $dblink_window->border_width(5); 733 734 # Create a scrolled window to pack the CList widget into 735 my $scrolled_window = new Gtk::ScrolledWindow( undef, undef ); 736 $dblink_window->vbox->pack_start( $scrolled_window, $true, $true, 0 ); 737 $scrolled_window->set_policy( 'automatic', 'always' ); 738 739 # Create the CList. For this example we use 2 columns 740 $dblink_clist = new_with_titles Gtk::CList( "Primary Id","Database" ); 741 742 # When a selection is made, we want to know about it. The callback 743 # used is selection_made, and its code can be found further down 744 $dblink_handler_id = $dblink_clist->signal_connect( "select_row", 745 sub{ return if (!defined($seq[$current])); 746 my ( $clist, $row ) = @_; 747 &store_current_dblink; 748 $current_dblink = $row; 749 &update_dblink_window; 750 } ); 751 752 # It isn't necessary to shadow the border, but it looks nice :) 753 $dblink_clist->set_shadow_type( 'out' ); 754 755 # What however is important, is that we set the column widths as 756 # they will never be right otherwise. Note that the columns are 757 # numbered from 0 and up (to 1 in this case). 758 $dblink_clist->set_column_width( 0, 150 ); 759 760 # Add the CList widget to the vertical box 761 $scrolled_window->add( $dblink_clist ); 762 763 my $bbox = new Gtk::HBox( $false, 5 ); 764 $bbox->border_width(10); 765 my $arrow = new Gtk::Arrow('down','out'); 766 my $button = new Gtk::Button(); 767 $button->add($arrow); 768 $bbox->pack_end( $button, $false, $false, 0); 769 $button->signal_connect 770 ( "clicked", 771 # next dblink button handler 772 sub { return if (!defined($seq[$current])); 773 &store_current_dblink; 774 $current_dblink++ 775 if ($current_dblink <((scalar $seq[$current]->annotation->each_DBLink)-1)); 776 &update_dblink_window; 777 } ); 778 779 $arrow = new Gtk::Arrow('up','out'); 780 $button = new Gtk::Button(); 781 $button->add($arrow); 782 $bbox->pack_end( $button, $false, $false, 0); 783 $button->signal_connect( "clicked", 784 # prev comment button handler 785 sub { return if (!defined($seq[$current])); 786 &store_current_dblink; 787 $current_dblink-- 788 if ($current_dblink > 0); 789 &update_dblink_window; 790 } ); 791 792 $button = new Gtk::Button("Add"); 793 $bbox->pack_start( $button, $false, $false, 0); 794 $button->signal_connect( "clicked", 795 # add comment button handler 796 sub { return if (!defined($seq[$current])); 797 &store_current_dblink; 798 my $dblink = new Bio::Annotation::DBLink; 799 $dblink->primary_id("<New>"); 800 $seq[$current]->annotation->add_DBLink( $dblink ); 801 $current_dblink = $seq[$current]->annotation->each_DBLink - 1; 802 $dblink_clist->append("",""); 803 &update_dblink_window; 804 } ); 805 806 $button = new Gtk::Button("Delete"); 807 $bbox->pack_start( $button, $false, $false, 0); 808 $button->signal_connect( "clicked", 809 # delete comment button handler 810 sub { return if !defined($seq[$current]); 811 $seq[$current]->annotation->remove_DBLink( $current_dblink ); 812 $dblink_clist->remove($current_dblink); 813 $current_dblink-- if ($current_dblink > 0); 814 &update_dblink_window; 815 } ); 816 817 $dblink_window->vbox->pack_start( $bbox, $false, $false, 0); 818 819 # horizontal box containing primary_id & optional_id entries 820 my $hbox; 821 $hbox = new Gtk::HBox( $true, 10 ); 822 $hbox->border_width( 1 ); 823 824 # text entries 825 $dblink_entry[0] = new Gtk::Entry(); 826 my $frame = new Gtk::Frame("primary id"); 827 $frame->add($dblink_entry[0]); 828 $hbox->pack_start( $frame, $true, $true, 0); 829 830 $dblink_entry[1] = new Gtk::Entry(); 831 $frame = new Gtk::Frame("optional id"); 832 $frame->add($dblink_entry[1]); 833 $hbox->pack_end( $frame, $true, $true, 0); 834 835 $dblink_window->vbox->pack_start( $hbox, $false, $false, 5); 836 837 $dblink_entry[2] = new Gtk::Entry(); 838 $frame = new Gtk::Frame("Database"); 839 $frame->add($dblink_entry[2]); 840 $dblink_window->vbox->pack_start( $frame, $false, $false, 5); 841 842 $dblink_entry[3] = new Gtk::Entry(); 843 $frame = new Gtk::Frame("Comment"); 844 $frame->add($dblink_entry[3]); 845 $dblink_window->vbox->pack_end( $frame, $false, $false, 5); 846 847 $bbox = new Gtk::HButtonBox(); 848 $bbox->set_layout("end"); 849 850 $button = new Gtk::Button( "Close" ); 851 $bbox->add( $button ); 852 $button->signal_connect("clicked", 853 # close button handler 854 sub{ $dblink_window->hide(); 855 &store_current_dblink; 856 }); 857 858 $dblink_window->action_area->pack_start( $bbox, $true, $true, 0 ); 859 $dblink_window->signal_connect_after( "delete_event", 860 # window delete handler 861 sub{ $dblink_window->hide(); 862 &store_current_dblink; 863 return &Gtk::true; 864 }); 865} 866 867sub store_current_dblink 868{ 869 if ((defined($seq[$current])) && ($seq[$current]->annotation->each_DBLink)) 870 { 871 (($seq[$current]->annotation->each_DBLink)[$current_dblink])-> 872 primary_id($dblink_entry[0]->get_chars(0,-1) ); 873 (($seq[$current]->annotation->each_DBLink)[$current_dblink])-> 874 optional_id($dblink_entry[1]->get_chars(0,-1) ); 875 (($seq[$current]->annotation->each_DBLink)[$current_dblink])-> 876 database($dblink_entry[2]->get_chars(0,-1) ); 877 (($seq[$current]->annotation->each_DBLink)[$current_dblink])-> 878 comment($dblink_entry[3]->get_chars(0,-1) ); 879 } 880} 881 882sub update_dblink_window 883{ 884 my ($show_me) = @_; 885 $dblink_window->show_all() if (defined($show_me)); 886 887 $dblink_clist->freeze(); 888 if (!defined($seq[$current])) 889 { 890 $dblink_clist->clear(); 891 $dblink_clist->thaw(); 892 foreach (@dblink_entry) { $_->set_text(""); } 893 return; 894 } 895 my @dblinks = $seq[$current]->annotation->each_DBLink; 896 # reset clist if rows are different to links 897 if ($dblink_clist->rows != @dblinks) { 898 $dblink_clist->clear(); 899 foreach (@dblinks) { $dblink_clist->append("",""); } 900 } 901 # redraw references 902 for(my $i=0;$i<@dblinks;$i++) 903 { 904 $dblink_clist->set_text($i,0,$dblinks[$i]->primary_id); 905 $dblink_clist->set_text($i,1,$dblinks[$i]->database); 906 } 907 # redraw text widgets 908 foreach (@dblink_entry) { $_->set_text(""); } 909 if (@dblinks) 910 { 911 $dblink_entry[0]->set_text($dblinks[$current_dblink]->primary_id); 912 $dblink_entry[1]->set_text($dblinks[$current_dblink]->optional_id); 913 $dblink_entry[2]->set_text($dblinks[$current_dblink]->database); 914 $dblink_entry[3]->set_text($dblinks[$current_dblink]->comment); 915 } 916 917 $dblink_clist->moveto($current_dblink,0,0.3,0.0) 918 if ($dblink_clist->row_is_visible($current_dblink) ne 'full'); 919 $dblink_clist->signal_handler_block($dblink_handler_id); 920 $dblink_clist->select_row($current_dblink,0); 921 $dblink_clist->signal_handler_unblock($dblink_handler_id); 922 Gtk::CList::set_focus_row($dblink_clist,$current_dblink); 923 $dblink_clist->thaw(); 924} 925 926sub init_reference_window 927{ 928 $current_ref = 0; 929 930 $ref_window = new Gtk::Dialog(); 931 $ref_window->set_default_size(620,500); 932 $ref_window->set_policy($true,$true,$false); 933 $ref_window->set_title("References"); 934 $ref_window->border_width(5); 935 936 # Create a scrolled window to pack the CList widget into 937 my $scrolled_window = new Gtk::ScrolledWindow( undef, undef ); 938 $ref_window->vbox->pack_start( $scrolled_window, $true, $true, 0 ); 939 $scrolled_window->set_policy( 'automatic', 'always' ); 940 941 # Create the CList. For this example we use 2 columns 942 $ref_clist = new_with_titles Gtk::CList( "Medline","Title","Authors" ); 943 944 # When a selection is made, we want to know about it. The callback 945 # used is selection_made, and its code can be found further down 946 $ref_handler_id = $ref_clist->signal_connect( "select_row", 947 sub{ return if (!defined($seq[$current])); 948 my ( $clist, $row ) = @_; 949 &store_current_reference; 950 $current_ref = $row; 951 &update_reference_window; 952 } ); 953 954 # It isn't necessary to shadow the border, but it looks nice :) 955 $ref_clist->set_shadow_type( 'out' ); 956 957 # What however is important, is that we set the column widths as 958 # they will never be right otherwise. Note that the columns are 959 # numbered from 0 and up (to 1 in this case). 960 $ref_clist->set_column_width( 0, 70 ); 961 $ref_clist->set_column_width( 1, 350 ); 962 $ref_clist->set_column_width( 2, 300 ); 963 964 # Add the CList widget to the vertical box 965 $scrolled_window->add( $ref_clist ); 966 967 my $bbox = new Gtk::HBox( $false, 5 ); 968 $bbox->border_width(10); 969 my $arrow = new Gtk::Arrow('down','out'); 970 my $button = new Gtk::Button(); 971 $button->add($arrow); 972 $bbox->pack_end( $button, $false, $false, 0); 973 $button->signal_connect 974 ( "clicked", 975 # next ref button handler 976 sub { return if (!defined($seq[$current])); 977 &store_current_reference; 978 $current_ref++ 979 if ($current_ref <((scalar $seq[$current]->annotation->each_Reference)-1)); 980 &update_reference_window; 981 } ); 982 983 $arrow = new Gtk::Arrow('up','out'); 984 $button = new Gtk::Button(); 985 $button->add($arrow); 986 $bbox->pack_end( $button, $false, $false, 0); 987 $button->signal_connect( "clicked", 988 # prev comment button handler 989 sub { return if (!defined($seq[$current])); 990 &store_current_reference; 991 $current_ref-- 992 if ($current_ref > 0); 993 &update_reference_window; 994 } ); 995 996 $button = new Gtk::Button("Add"); 997 $bbox->pack_start( $button, $false, $false, 0); 998 $button->signal_connect( "clicked", 999 # add comment button handler 1000 sub { return if (!defined($seq[$current])); 1001 &store_current_reference; 1002 my $ref = new Bio::Annotation::Reference; 1003 $ref->medline("<New>"); 1004 $seq[$current]->annotation->add_Reference( $ref ); 1005 $ref_clist->append("","",""); 1006 $current_ref = ($seq[$current]->annotation->each_Reference)-1; 1007 &update_reference_window; 1008 } ); 1009 1010 $button = new Gtk::Button("Delete"); 1011 $bbox->pack_start( $button, $false, $false, 0); 1012 $button->signal_connect( "clicked", 1013 # delete comment button handler 1014 sub { return if !defined($seq[$current]); 1015 $seq[$current]->annotation->remove_Reference( $current_ref ); 1016 $ref_clist->remove($current_ref); 1017 $current_ref-- if ($current_ref > 0); 1018 &update_reference_window; 1019 } ); 1020 1021 $ref_window->vbox->pack_start( $bbox, $false, $false, 0); 1022 1023 # horizontal box containing primary_id & optional_id entries 1024 my $hbox; 1025 $hbox = new Gtk::HBox( $true, 10 ); 1026 $hbox->border_width( 1 ); 1027 1028 # text entries 1029 $ref_entry[0] = new Gtk::Entry(); 1030 my $frame = new Gtk::Frame("Title"); 1031 $frame->add($ref_entry[0]); 1032 $ref_window->vbox->pack_start( $frame, $false, $false, 5); 1033 1034 $ref_entry[1] = new Gtk::Entry(); 1035 $frame = new Gtk::Frame("Authors"); 1036 $frame->add($ref_entry[1]); 1037 $ref_window->vbox->pack_start( $frame, $false, $false, 5); 1038 1039 # horizontal box 1040 $hbox = new Gtk::HBox( $true, 10 ); 1041 $hbox->border_width( 1 ); 1042 1043 # text entries 1044 $ref_entry[2] = new Gtk::Entry(); 1045 $frame = new Gtk::Frame("Comment"); 1046 $frame->add($ref_entry[2]); 1047 $hbox->pack_start( $frame, $true, $true, 0); 1048 1049 $ref_entry[3] = new Gtk::Entry(); 1050 $frame = new Gtk::Frame("Location"); 1051 $frame->add($ref_entry[3]); 1052 $hbox->pack_end( $frame, $true, $true, 0); 1053 1054 $ref_window->vbox->pack_start( $hbox, $false, $false, 5); 1055 1056 # horizontal box 1057 $hbox = new Gtk::HBox( $false, 10 ); 1058 $hbox->border_width( 1 ); 1059 1060 # text entries 1061 $ref_entry[4] = new Gtk::Entry(); 1062 $frame = new Gtk::Frame("Medline"); 1063 $frame->add($ref_entry[4]); 1064 $hbox->pack_start( $frame, $false, $false, 0); 1065 1066# $ref_entry[5] = new Gtk::Entry(); 1067# $frame = new Gtk::Frame("Start"); 1068# $frame->add($ref_entry[5]); 1069# $hbox->pack_start( $frame, $false, $false, 0); 1070 1071 $ref_entry[5] = new Gtk::Entry(); 1072 $frame = new Gtk::Frame("Reference Position"); 1073 $frame->add($ref_entry[5]); 1074 $hbox->pack_end( $frame, $true, $true, 0); 1075 1076 $ref_window->vbox->pack_start( $hbox, $false, $false, 5); 1077 1078 1079 $bbox = new Gtk::HButtonBox(); 1080 $bbox->set_layout("end"); 1081 1082 $button = new Gtk::Button( "Close" ); 1083 $bbox->add( $button ); 1084 $button->signal_connect("clicked", 1085 # close button handler 1086 sub{ $ref_window->hide(); 1087 &store_current_reference; 1088 }); 1089 1090 $ref_window->action_area->pack_start( $bbox, $true, $true, 0 ); 1091 $ref_window->signal_connect_after( "delete_event", 1092 # window delete handler 1093 sub{ $ref_window->hide(); 1094 &store_current_reference; 1095 return &Gtk::true; 1096 }); 1097} 1098 1099sub store_current_reference 1100{ 1101 if ((defined($seq[$current])) && ($seq[$current]->annotation->each_Reference)) 1102 { 1103 (($seq[$current]->annotation->each_Reference)[$current_ref])-> 1104 title($ref_entry[0]->get_chars(0,-1) ); 1105 (($seq[$current]->annotation->each_Reference)[$current_ref])-> 1106 authors($ref_entry[1]->get_chars(0,-1) ); 1107 (($seq[$current]->annotation->each_Reference)[$current_ref])-> 1108 comment($ref_entry[2]->get_chars(0,-1) ); 1109 (($seq[$current]->annotation->each_Reference)[$current_ref])-> 1110 location($ref_entry[3]->get_chars(0,-1) ); 1111 (($seq[$current]->annotation->each_Reference)[$current_ref])-> 1112 medline($ref_entry[4]->get_chars(0,-1) ); 1113# (($seq[$current]->annotation->each_Reference)[$current_ref])-> 1114# start($ref_entry[5]->get_chars(0,-1) ); 1115 (($seq[$current]->annotation->each_Reference)[$current_ref])-> 1116 rp($ref_entry[5]->get_chars(0,-1) ); 1117 } 1118} 1119 1120sub update_reference_window 1121{ 1122 my ($show_me) = @_; 1123 $ref_window->show_all() if (defined($show_me)); 1124 1125 $ref_clist->freeze(); 1126 if (!defined($seq[$current])) 1127 { 1128 $ref_clist->clear(); 1129 $ref_clist->thaw(); 1130 foreach (@ref_entry) { $_->set_text(""); } 1131 return; 1132 } 1133 my @refs = $seq[$current]->annotation->each_Reference; 1134 # reset clist if rows are different to references 1135 if ($ref_clist->rows != @refs) { 1136 $ref_clist->clear(); 1137 foreach (@refs) { $ref_clist->append("","",""); } 1138 } 1139 # redraw references 1140 for(my $i=0;$i<@refs;$i++) 1141 { 1142 $ref_clist->set_text($i,0,$refs[$i]->medline) 1143 if ($refs[$i]->medline); 1144 $ref_clist->set_text($i,1,$refs[$i]->title) 1145 if ($refs[$i]->title); 1146 $ref_clist->set_text($i,2,$refs[$i]->authors) 1147 if ($refs[$i]->authors); 1148 } 1149 # redraw text widgets 1150 foreach (@ref_entry) { $_->set_text(""); } 1151 if (@refs) { 1152 $ref_entry[0]->set_text($refs[$current_ref]->title); 1153 $ref_entry[1]->set_text($refs[$current_ref]->authors); 1154 $ref_entry[2]->set_text($refs[$current_ref]->comment); 1155 $ref_entry[3]->set_text($refs[$current_ref]->location); 1156 $ref_entry[4]->set_text($refs[$current_ref]->medline); 1157# $ref_entry[5]->set_text($refs[$current_ref]->start); 1158 $ref_entry[5]->set_text($refs[$current_ref]->rp); 1159 } 1160 1161 $ref_clist->moveto($current_ref,0,0.3,0.0) 1162 if ($ref_clist->row_is_visible($current_ref) ne 'full'); 1163 $ref_clist->signal_handler_block($ref_handler_id); 1164 $ref_clist->select_row($current_ref,0); 1165 $ref_clist->signal_handler_unblock($ref_handler_id); 1166 Gtk::CList::set_focus_row($ref_clist,$current_ref); 1167 $ref_clist->thaw(); 1168} 1169 1170 1171sub init_about_dialog { 1172 my ($window,$bg,$tbox,$vbox,$hbox,$sep,$butbox,$button,$pixmap); 1173 $about_dialog = new Gtk::Window("dialog"); 1174 $about_dialog->set_title("About gSequence"); 1175 $about_dialog->signal_connect_after("destroy" => 1176 sub { $about_dialog->hide; 1177 return &Gtk::true; }); 1178 $about_dialog->set_default_size('350','350'); 1179 $about_dialog->set_policy(1,1,0); 1180 $window = $about_dialog->window; 1181 $bg = $about_dialog->style->bg('normal'); 1182 $vbox= new Gtk::VBox(0,0); 1183 $about_dialog->add($vbox); 1184 $tbox = new Gtk::Label("\ngSequence\nAuthor: Lorenz Pollak\n\n 1185gSequence is cool! :-)\n(this text is to be written...) 1186\n"); 1187 $vbox->pack_start($tbox,1,1,1); 1188 1189 $hbox = new Gtk::HBox(0,0); 1190 $vbox->pack_start($hbox,0,0,0); 1191 $sep = new Gtk::HSeparator; 1192 $sep->set_usize(-1,5); 1193 $vbox->pack_start($sep,0,1,0); 1194 1195 $butbox = new Gtk::HButtonBox; 1196 $butbox->set_usize(-1,32); 1197 $vbox->pack_start($butbox, 0,1,0); 1198 $button = new_with_label Gtk::Button("OK"); 1199 $button->set_usize(50,-1); 1200 $button->signal_connect('clicked', sub { $about_dialog->hide; }); 1201 $button->can_default(1); 1202 $button->grab_default; 1203 $butbox->add($button); 1204 1205 return 1; 1206} 1207 1208sub init_feature_window 1209{ 1210 $current_feature_item = 0; 1211 1212 $feature_window = new Gtk::Dialog(); 1213 $feature_window->set_default_size(500,400); 1214 $feature_window->set_policy($true,$true,$false); 1215 $feature_window->set_title("Sequence Features"); 1216 $feature_window->border_width(5); 1217 1218 my $pane = new Gtk::HPaned(); 1219 $feature_window->vbox->pack_start( $pane, $true, $true, 0); 1220 $pane->set_handle_size( 10 ); 1221 $pane->set_gutter_size( 8 ); 1222 1223 # Create a VBox for the Entry and Tree Scrolled Window 1224 my $vbox = new Gtk::VBox( $false, 0 ); 1225 $pane->add1( $vbox ); 1226 1227 # Create a ScrolledWindow for the tree 1228 my $tree_scrolled_win = new Gtk::ScrolledWindow( undef, undef ); 1229 $tree_scrolled_win->set_usize( 150, 400 ); 1230 $vbox->pack_start( $tree_scrolled_win, $true, $true, 0 ); 1231 $tree_scrolled_win->set_policy( 'automatic', 'automatic' ); 1232 1233 #my $list_scrolled_win = new Gtk::ScrolledWindow( undef, undef ); 1234 #$list_scrolled_win->set_policy( 'automatic', 'automatic' ); 1235 $vbox = new Gtk::VBox( $false, 0 ); 1236 $pane->add2( $vbox ); 1237 1238 # add stuff to the vbox 1239 # text entries 1240 my $hbox = new Gtk::HBox( $true, 10 ); 1241 1242 $feature_entry[0] = new Gtk::Entry(); 1243 my $frame = new Gtk::Frame("Primary Tag"); 1244 $frame->add($feature_entry[0]); 1245 $hbox->pack_start( $frame, $true, $true, 0); 1246 1247 $feature_entry[1] = new Gtk::Entry(); 1248 $frame = new Gtk::Frame("Source Tag"); 1249 $frame->add($feature_entry[1]); 1250 $hbox->pack_end( $frame, $true, $true, 0); 1251 1252 $vbox->pack_start( $hbox, $false, $false, 5); 1253 1254 $hbox = new Gtk::HBox( $true, 10 ); 1255 1256 my $adj = new Gtk::Adjustment( 0, 0, 0, 0, 0, 0 ); 1257 $feature_spinner[0] = new Gtk::SpinButton( $adj, 0.0, 0 ); 1258 $feature_spinner[0]->signal_connect( "changed", \&select_feature_region); 1259 $frame = new Gtk::Frame("Start"); 1260 $frame->add($feature_spinner[0]); 1261 $hbox->pack_start( $frame, $true, $true, 0); 1262 1263 $adj = new Gtk::Adjustment( 0, 0, 0, 0, 0, 0 ); 1264 $feature_spinner[1] = new Gtk::SpinButton( $adj, 0.0, 0 ); 1265 $feature_spinner[1]->signal_connect( "changed", \&select_feature_region); 1266 $frame = new Gtk::Frame("End"); 1267 $frame->add($feature_spinner[1]); 1268 $hbox->pack_start( $frame, $true, $true, 0); 1269 1270 $frame = new Gtk::Frame("Strand"); 1271 $hbox->pack_start( $frame, $true, $true, 0); 1272 $frame = new Gtk::Frame("Score"); 1273 $hbox->pack_start( $frame, $true, $true, 0); 1274 1275 $vbox->pack_start( $hbox, $false, $false, 5); 1276 1277 $feature_entry[2] = new Gtk::Entry(); 1278 $frame = new Gtk::Frame("Description"); 1279 $frame->add($feature_entry[2]); 1280 1281 $vbox->pack_start( $frame, $false, $false, 5); 1282 1283 my $bbox = new Gtk::HBox( $false, 5 ); 1284 $bbox->border_width(10); 1285 my $button = new Gtk::Button("Add"); 1286 $bbox->pack_start( $button, $false, $false, 0); 1287 $button->signal_connect( "clicked", 1288 # add comment button handler 1289 sub { return if (!defined($seq[$current])); 1290 &store_current_feature if ($current_feature_item); 1291 my $feature = new Bio::SeqFeature::Generic; 1292 $feature->primary_tag("<New>"); 1293 $seq[$current]->add_SeqFeature( $feature ); 1294 my $item_new = new_with_label Gtk::TreeItem( "<New>" ); 1295 $item_new->set_user_data( $feature ); 1296 $item_new->signal_connect( 'select', \&select_feature_item ); 1297 $current_feature_item->parent->append( $item_new ) 1298 if ($current_feature_item); 1299 $feature_tree->append( $item_new ) if (!$current_feature_item); 1300 $item_new->show(); 1301 $current_feature_item->deselect() 1302 if ($current_feature_item); 1303 $item_new->select(); 1304 } ); 1305 $button = new Gtk::Button("Add Subfeature"); 1306 $bbox->pack_start( $button, $false, $false, 0); 1307 $button->signal_connect( "clicked", 1308 # add comment button handler 1309 sub { return if (!defined($seq[$current])||!$current_feature_item); 1310 &store_current_feature; 1311 my $feature = new Bio::SeqFeature::Generic; 1312 $feature->primary_tag("<New>"); 1313 $feature->start($current_feature_item->get_user_data->start); 1314 $feature->end($current_feature_item->get_user_data->end); 1315 $current_feature_item->get_user_data->add_sub_SeqFeature( $feature ); 1316 my $new_subtree = new Gtk::Tree(); 1317 $current_feature_item->set_subtree( $new_subtree ); 1318 my $item_new = new_with_label Gtk::TreeItem( "<New>" ); 1319 $item_new->set_user_data( $feature ); 1320 $item_new->signal_connect( 'select', \&select_feature_item ); 1321 $new_subtree->append( $item_new ); 1322 $item_new->show(); 1323 $current_feature_item->deselect(); 1324 $current_feature_item->expand(); 1325 $item_new->select(); 1326 } ); 1327 $button = new Gtk::Button("Delete"); 1328 $bbox->pack_start( $button, $false, $false, 0); 1329 $button->signal_connect( "clicked", 1330 # delete comment button handler 1331 sub { return if (!$current_feature_item); 1332 &store_current_feature; 1333 my $flist = $seq[$current]->{_as_feat}; 1334 my $pos; 1335 for(my $i=0;$i<@$flist;$i++) { 1336 $pos=$i if $$flist[$i]==$current_feature_item->get_user_data(); 1337 } 1338 splice @$flist, $pos, 1; 1339 $seq[$current]->{_as_feat} = $flist; 1340 $current_feature_item->parent->remove_item($current_feature_item); 1341 $current_feature_item=0; 1342 } ); 1343 1344 $vbox->pack_end( $bbox, $false, $false, 0); 1345 1346 # Create root tree 1347 $feature_tree = new Gtk::Tree(); 1348 $tree_scrolled_win->add_with_viewport( $feature_tree ); 1349 $feature_tree->set_selection_mode( 'single' ); 1350 $feature_tree->set_view_mode( 'item' ); 1351 1352 $bbox = new Gtk::HButtonBox(); 1353 $bbox->set_layout("end"); 1354 1355 $button = new Gtk::Button( "Close" ); 1356 $bbox->add( $button ); 1357 $button->signal_connect("clicked", 1358 # close button handler 1359 sub{ $feature_window->hide(); 1360 &store_current_feature; 1361 }); 1362 1363 $feature_window->action_area->pack_start( $bbox, $true, $true, 0 ); 1364 $feature_window->signal_connect_after( "delete_event", 1365 # window delete handler 1366 sub{ $feature_window->hide(); 1367 &store_current_feature; 1368 return &Gtk::true; 1369 }); 1370} 1371 1372# Callback for expanding tree 1373sub expand_feature_tree 1374 { 1375 my ( $item, $subtree ) = @_; 1376 my ($feature,$subfeature,$item_new,$new_subtree); 1377 $feature = $item->get_user_data(); 1378 1379 foreach $subfeature ($feature->sub_SeqFeature) 1380 { 1381 $item_new = new_with_label Gtk::TreeItem( $subfeature->primary_tag ); 1382 $item_new->set_user_data( $subfeature ); 1383 $item_new->signal_connect( 'select', \&select_feature_item ); 1384 $subtree->append( $item_new ); 1385 $item_new->show(); 1386 1387 if ( $subfeature->sub_SeqFeature ) 1388 { 1389 $new_subtree = new Gtk::Tree(); 1390 $item_new->set_subtree( $new_subtree ); 1391 $item_new->signal_connect( 'expand', 1392 \&expand_feature_tree, 1393 $new_subtree ); 1394 $item_new->signal_connect( 'collapse', \&collapse_feature_tree ); 1395 } 1396 $item_new->expand(); 1397 } 1398 } 1399 1400 1401# Callback for collapsing tree 1402sub collapse_feature_tree 1403 { 1404 my ( $item ) = @_; 1405 1406 my $subtree = new Gtk::Tree(); 1407 1408 $item->remove_subtree(); 1409 $item->set_subtree( $subtree ); 1410 $item->signal_connect( 'expand', \&expand_feature_tree, $subtree ); 1411 } 1412 1413 1414sub store_current_feature 1415{ 1416 if ((defined($seq[$current])) && ($seq[$current]->top_SeqFeatures) && ($current_feature_item)) 1417 { 1418 my $current_feature = $current_feature_item->get_user_data(); 1419 $current_feature->primary_tag( $feature_entry[0]->get_chars(0,-1) ); 1420 $current_feature->source_tag( $feature_entry[1]->get_chars(0,-1) ); 1421 if ($current_feature->has_tag("description")) 1422 { 1423 $current_feature->remove_tag("description"); 1424 $current_feature->add_tag_value("description", 1425 $feature_entry[2]->get_chars(0,-1)); 1426 } 1427 $current_feature->start($feature_spinner[0]->get_value_as_int()); 1428 $current_feature->end($feature_spinner[1]->get_value_as_int()); 1429 # set tree item 1430 ($current_feature_item->children)[0]->set($current_feature->primary_tag); 1431 } 1432} 1433 1434sub select_feature_item 1435{ 1436 my ($widget) = @_; 1437 &store_current_feature; 1438 $current_feature_item->deselect() 1439 if $current_feature_item; 1440 $current_feature_item = $widget; 1441 &update_feature_paned2; 1442} 1443 1444sub update_feature_paned2 1445{ 1446 $feature_entry[0]->set_text(""); 1447 $feature_entry[1]->set_text(""); 1448 $feature_entry[2]->set_text(""); 1449 1450 return if (!defined($seq[$current])||(!$current_feature_item)); 1451 my $current_feature = $current_feature_item->get_user_data(); 1452 $feature_entry[0]->set_text($current_feature->primary_tag); 1453 $feature_entry[1]->set_text($current_feature->source_tag) 1454 if (defined($current_feature->source_tag)); 1455 $feature_entry[2]->set_text(($current_feature->each_tag_value("description"))[0]) 1456 if ($current_feature->has_tag("description")); 1457 my $adj = new Gtk::Adjustment($current_feature->start, 1458 0, 1459 $seq[$current]->length-1, 1460 1, 1461 1, 1462 0 1463 ); 1464 $feature_spinner[0]->set_adjustment($adj); 1465 $feature_spinner[0]->set_value($current_feature->start); 1466 $feature_spinner[0]->show_all(); 1467 $adj = new Gtk::Adjustment($current_feature->end, 1468 0, 1469 $seq[$current]->length-1, 1470 1, 1471 1, 1472 0 1473 ); 1474 $feature_spinner[1]->set_adjustment($adj); 1475 $feature_spinner[1]->set_value($current_feature->end); 1476 $feature_spinner[1]->show_all(); 1477} 1478 1479sub select_feature_region 1480{ 1481 $seq_edit[$current]->freeze; 1482 $seq_edit[$current]->select_region($feature_spinner[0]->get_value_as_int(), 1483 $feature_spinner[1]->get_value_as_int()+1); 1484 $seq_edit[$current]->thaw; 1485} 1486 1487sub update_feature_window 1488{ 1489 my ($show_me) = @_; 1490 $feature_window->show_all() if (defined($show_me)); 1491 1492 $feature_tree->clear_items(0,-1); 1493 if (!defined($seq[$current])) 1494 { 1495 &update_feature_paned2; 1496 return; 1497 } 1498 1499 my ($item_new,$new_subtree); 1500 foreach ($seq[$current]->top_SeqFeatures) 1501 { 1502 $item_new = new_with_label Gtk::TreeItem( $_->primary_tag ); 1503 $item_new->set_user_data( $_ ); 1504 $item_new->signal_connect( 'select', \&select_feature_item ); 1505 $feature_tree->append( $item_new ); 1506 if ( $_->sub_SeqFeature ) 1507 { 1508 $new_subtree = new Gtk::Tree(); 1509 $item_new->set_subtree( $new_subtree ); 1510 $item_new->signal_connect( 'expand', 1511 \&expand_feature_tree, 1512 $new_subtree ); 1513 $item_new->signal_connect( 'collapse', \&collapse_feature_tree ); 1514 } 1515 $item_new->expand(); 1516 } 1517 $feature_tree->select_item($current_feature_item) 1518 if $current_feature_item; 1519 $feature_tree->show_all(); 1520 1521 &update_feature_paned2; 1522} 1523 1524sub store_prefs 1525{ 1526} 1527 1528sub update_pref_window 1529{ 1530 $pref_window->show_all(); 1531} 1532 1533sub init_pref_window 1534{ 1535 $pref_window = new Gtk::Dialog(); 1536 $pref_window->set_default_size(500,400); 1537 $pref_window->set_policy($true,$true,$false); 1538 $pref_window->border_width( 5 ); 1539 1540 # Create a new notebook, place the position of the tabs 1541 my $notebook = new Gtk::Notebook(); 1542 $pref_window->vbox->pack_start( $notebook, $true, $true, 0); 1543 $notebook->set_tab_pos( 'top' ); 1544 1545 my $main_vbox = new Gtk::VBox($false,10); 1546 1547 my $label = new Gtk::Label( "Import Options" ); 1548 my $frame = new Gtk::Frame("Flat File Indexes"); 1549 my $vbox = new Gtk::VBox($false,10); 1550 $frame->add($vbox); 1551 $main_vbox->pack_start($frame,$false,$false,10); 1552 1553 $notebook->append_page( $main_vbox, $label ); 1554 1555 my $hbox = new Gtk::HBox($false,0); 1556 1557 $pref_entry[0] = new Gtk::Entry(); 1558 $frame = new Gtk::Frame("Indexes Directory"); 1559 $frame->add($pref_entry[0]); 1560 $hbox->pack_start( $frame, $true, $false, 0); 1561 1562 $pref_entry[1] = new Gtk::Entry(); 1563 $frame = new Gtk::Frame("Index Type"); 1564 $frame->add($pref_entry[1]); 1565 $hbox->pack_start( $frame, $false, $false, 0); 1566 1567 $vbox->pack_start( $hbox, $false, $false, 0); 1568 1569 $pref_entry[2] = new Gtk::Entry(); 1570 $frame = new Gtk::Frame("Fasta Index Name"); 1571 $frame->add($pref_entry[2]); 1572 $vbox->pack_start( $frame, $false, $false, 0); 1573 1574 $pref_entry[3] = new Gtk::Entry(); 1575 $frame = new Gtk::Frame("SwissProt Index Name"); 1576 $frame->add($pref_entry[3]); 1577 $vbox->pack_start( $frame, $false, $false, 0); 1578 1579 $pref_entry[4] = new Gtk::Entry(); 1580 $frame = new Gtk::Frame("SwissPfam Index Name"); 1581 $frame->add($pref_entry[4]); 1582 $vbox->pack_start( $frame, $false, $false, 0); 1583 1584 $frame = new Gtk::Frame("Remote DBs"); 1585 $hbox = new Gtk::HBox($false,10); 1586 $frame->add($hbox); 1587 $main_vbox->pack_start($frame,$false,$false,10); 1588 1589 $pref_entry[5] = new Gtk::Entry(); 1590 $frame = new Gtk::Frame("AceDB host"); 1591 $frame->add($pref_entry[5]); 1592 $hbox->pack_start( $frame, $true, $false, 0); 1593 1594 $pref_entry[6] = new Gtk::Entry(); 1595 $frame = new Gtk::Frame("AceDB port"); 1596 $frame->add($pref_entry[6]); 1597 $hbox->pack_start( $frame, $false, $false, 0); 1598 1599 $notebook->set_page( 0 ); 1600 1601 my $bbox = new Gtk::HButtonBox(); 1602 $bbox->set_layout("end"); 1603 1604 my $button = new Gtk::Button( "Save" ); 1605 $bbox->add( $button ); 1606 $button->signal_connect("clicked", 1607 # close button handler 1608 sub{ $pref_window->hide(); 1609 &store_prefs(); 1610 }); 1611 1612 $button = new Gtk::Button( "Close" ); 1613 $bbox->add( $button ); 1614 $button->signal_connect("clicked", 1615 # close button handler 1616 sub{ $pref_window->hide(); 1617 }); 1618 1619 $pref_window->action_area->pack_start( $bbox, $true, $true, 0 ); 1620 $pref_window->signal_connect_after( "delete_event", 1621 # window delete handler 1622 sub{ $pref_window->hide(); 1623 return &Gtk::true; 1624 }); 1625} 1626