2 # gSequence - Protein Sequence Control Panel
5 # this is work in progress! use this only for testing
11 use Bio
::Tools
::SeqStats
;
12 use Bio
::SeqFeature
::Generic
;
13 use Bio
::Index
::Abstract
;
24 my ($main_notebook,@main_label,@seq_edit);
26 my ($import_dialog,$import_entry,@import_buttons,$import_from);
27 my ($description_window,$description_edit);
28 my ($comment_window,$comment_edit,$current_comment,$comment_frame);
29 my ($seqstats_window,$seqstats_edit);
30 my ($dblink_window,@dblink_entry,$current_dblink,$dblink_clist,$dblink_handler_id);
31 my ($ref_window,@ref_entry,$current_ref,$ref_clist,$ref_handler_id);
32 my ($feature_window,@feature_entry,$current_feature_item,@feature_spinner,
33 $feature_handler_id,$feature_tree);
34 my ($pref_window,@pref_entry);
40 my @locked; # locked sequence for editing ?
44 my @menu_items = ( { path
=> '/_File',
46 { path
=> '/File/_New',
47 accelerator
=> '<control>N',
49 { path
=> '/File/_Open SwissProt',
50 accelerator
=> '<control>O',
51 callback
=> \
&open_dialog
},
52 { path
=> '/File/_Save SwissProt',
53 accelerator
=> '<control>S',
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...',
63 { path
=> '/File/Import from.../Remote DB',
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',
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 ); } },
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); } },
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);} },
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' },
126 { path
=> '/_Options',
127 type
=> '<Branch>' },
128 { path
=> '/Options/_Preferences',
129 callback
=> sub {&update_pref_window
(1);} },
132 type
=> '<LastBranch>' },
133 { path
=> '/Help/Help' },
134 { path
=> '/Help/_About...',
135 callback
=> sub { $about_dialog->show_all();} } );
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
();
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 );
170 # vertical box containing menu and text editor widget
172 $main_vbox = new Gtk
::VBox
( $false, 1 );
173 $main_vbox->border_width( 1 );
174 $window->add( $main_vbox );
176 # handlebox for menubar
178 $handlebox = new Gtk
::HandleBox
();
179 $main_vbox->pack_start( $handlebox, $false, $true, 0 );
183 $menubar = get_menu
( $window );
184 $handlebox->add( $menubar );
187 $seq_edit[$current] = new Gtk
::Text
( undef, undef );
188 $seq_edit[$current]->set_editable( $true );
190 # vertical scrollbar for text widget
192 $scrollbar = new Gtk
::VScrollbar
( $seq_edit[$current]->vadj );
194 # horizontal box containing text widget and scrollbar
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);
201 $main_notebook = new Gtk
::Notebook
();
202 $main_notebook->set_tab_pos( 'top' );
204 $main_vbox->pack_end( $main_notebook, $true, $true, 0);
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
(); } );
224 $accel_group = new Gtk
::AccelGroup
();
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',
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 );
241 # Attach the new accelerator group to the window.
242 $window->add_accel_group( $accel_group );
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>' ) );
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]));
262 $seq_edit[$curr] = new Gtk
::Text
( undef, undef );
263 $seq_edit[$curr]->set_editable( $true );
265 # vertical scrollbar for text widget
267 $scrollbar = new Gtk
::VScrollbar
( $seq_edit[$curr]->vadj );
269 # horizontal box containing text widget and scrollbar
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);
276 $main_notebook->append_page( $seq_edit_hbox, $main_label[$curr] );
277 $main_notebook->show_all();
278 $main_notebook->set_page(-1);
283 my ($server,$port,$dir,$db); # read from preferences
286 return if (!defined($import_from) || !($import_from));
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");
296 if( $import_buttons[0]->get_active() ) {
297 &new_seq_page
($dbobj->get_Seq_by_id($import_entry->get_text()));
299 &new_seq_page
($dbobj->get_Seq_by_acc($import_entry->get_text()));
306 my %names = ( "ace" => "AceDB",
307 "genpept" => "GenPept DB",
308 "fasta" => "Fasta Flat File",
309 "swissprot" => "SwissProt Flat File",
310 "swisspfam" => "SwissPfam Flat File"
312 $import_dialog->set_title("Import from ".$names{$import_from});
313 $import_entry->set_text("");
314 $import_dialog->show_all();
317 sub init_import_dialog
319 $import_dialog = new Gtk
::Dialog
();
320 $import_dialog->border_width(5);
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);
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();
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);
336 my $bbox = new Gtk
::HButtonBox
();
337 $bbox->set_layout("end");
339 $button = new Gtk
::Button
( "OK" );
340 $bbox->add( $button );
341 $button->signal_connect("clicked",
343 sub{ $import_dialog->hide();
347 $button = new Gtk
::Button
( "Cancel" );
348 $bbox->add( $button );
349 $button->signal_connect("clicked",
350 # close button handler
351 sub{ $import_dialog->hide();
354 $import_dialog->action_area->pack_start( $bbox, $true, $true, 0 );
356 $import_dialog->signal_connect_after( "delete_event",
357 # window delete handler
358 sub{ $import_dialog->hide();
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",
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();
377 # Get the selected filename
380 my ( $widget, $file_selection ) = @_;
381 push @filename, $file_selection->get_filename();
383 $widget->parent->parent->parent->destroy();
385 my $in = Bio
::SeqIO
->new(-file
=> $filename[-1] , '-format' => 'swiss');
387 &new_seq_page
($in->next_seq());
392 $main_label[$current]->set_text($seq[$current]->id) if (defined($seq[$current]));
393 $main_label[$current]->set_text("<New>") if (!defined($seq[$current]));
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();
400 &update_comment_window
();
401 &update_description_window
();
402 &update_seqstats_window
();
403 &update_dblink_window
();
404 &update_reference_window
();
405 &update_feature_window
();
410 &new_seq_page
(undef);
419 if (!defined($filename[$current])||!$filename[$current])
424 my $out = Bio
::SeqIO
->new(-file
=> ">$filename[$current]" , '-format' => 'swiss');
425 $out->write_seq($seq[$current]);
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",
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();
442 # Get the selected filename and print it to the console
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]);
453 sub init_comment_window
455 $current_comment = 0;
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);
464 $comment_frame = new Gtk
::Frame
( "Comment[".$current_comment."]" );
467 $comment_edit = new Gtk
::Text
( undef, undef );
468 $comment_edit->set_editable( $true );
469 $comment_edit->set_word_wrap( $true );
471 # vertical scrollbar for text widget
473 $scrollbar = new Gtk
::VScrollbar
( $comment_edit->vadj );
475 # horizontal box containing text widget and scrollbar
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);
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
492 # next comment button handler
493 sub { return if !defined($seq[$current]);
494 &store_current_comment
;
496 if ($current_comment <((scalar $seq[$current]->annotation->each_Comment)-1));
497 &update_comment_window
;
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
;
509 if ($current_comment > 0);
510 &update_comment_window
;
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
;
521 $seq[$current]->annotation->add_Comment( $comment );
522 $current_comment = $seq[$current]->annotation->each_Comment - 1;
523 &update_comment_window
;
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
;
537 $comment_window->vbox->pack_end( $bbox, $false, $false, 0);
539 $bbox = new Gtk
::HButtonBox
();
540 $bbox->set_layout("end");
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
;
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
;
559 sub store_current_comment
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));
566 sub update_comment_window
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]))
575 my @comment = $seq[$current]->annotation->each_Comment;
576 $comment_edit->insert(undef,undef,undef, $comment[$current_comment]->text)
579 $comment_edit->thaw();
581 $comment_window->show_all() if (defined($show_me));
584 sub init_description_window
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");
592 my $description_frame = new Gtk
::Frame
( "Description" );
595 $description_edit = new Gtk
::Text
( undef, undef );
596 $description_edit->set_editable( $true );
597 $description_edit->set_word_wrap( $true );
599 # vertical scrollbar for text widget
601 $scrollbar = new Gtk
::VScrollbar
( $description_edit->vadj );
603 # horizontal box containing text widget and scrollbar
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);
612 my $bbox = new Gtk
::HButtonBox
();
613 $bbox->set_layout("end");
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);
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);
634 sub update_description_window
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();
643 $description_window->show_all() if (defined($show_me));
646 sub init_seqstats_window
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");
654 my $seqstats_frame = new Gtk
::Frame
( "Sequence Statistics" );
657 $seqstats_edit = new Gtk
::Text
( undef, undef );
658 $seqstats_edit->set_editable( $false );
659 $seqstats_edit->set_word_wrap( $true );
661 # vertical scrollbar for text widget
663 $scrollbar = new Gtk
::VScrollbar
( $seqstats_edit->vadj );
665 # horizontal box containing text widget and scrollbar
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);
674 my $bbox = new Gtk
::HButtonBox
();
675 $bbox->set_layout("end");
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();
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();
692 sub update_seqstats_window
695 my ($data,$weight,$count_hash,$percent);
697 $seqstats_edit->freeze();
698 $seqstats_edit->delete_text(0,-1);
699 if (defined($seq[$current]))
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";
706 $data .= "Molecular weight of sequence is greater than ";
707 $data .= $$weight[0]." and less than ".$$weight[1]."\n\n";
709 $count_hash = Bio
::Tools
::SeqStats
->count_monomers($seq[$current]->primary_seq);
710 $data .= "Amino Acids:\n";
711 foreach (sort keys %$count_hash)
713 $percent = sprintf "%.1f",
714 (($$count_hash{$_} / $seq[$current]->length)*100);
715 $data .= "${_}: ".$$count_hash{$_}." (${percent}%) \n"
717 $seqstats_edit->insert(undef,undef,undef,$data)
719 $seqstats_edit->thaw();
721 $seqstats_window->show_all() if (defined($show_me));
724 sub init_dblink_window
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);
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' );
739 # Create the CList. For this example we use 2 columns
740 $dblink_clist = new_with_titles Gtk
::CList
( "Primary Id","Database" );
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
;
752 # It isn't necessary to shadow the border, but it looks nice :)
753 $dblink_clist->set_shadow_type( 'out' );
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 );
760 # Add the CList widget to the vertical box
761 $scrolled_window->add( $dblink_clist );
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
771 # next dblink button handler
772 sub { return if (!defined($seq[$current]));
773 &store_current_dblink
;
775 if ($current_dblink <((scalar $seq[$current]->annotation->each_DBLink)-1));
776 &update_dblink_window
;
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
;
788 if ($current_dblink > 0);
789 &update_dblink_window
;
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
;
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
;
817 $dblink_window->vbox->pack_start( $bbox, $false, $false, 0);
819 # horizontal box containing primary_id & optional_id entries
821 $hbox = new Gtk
::HBox
( $true, 10 );
822 $hbox->border_width( 1 );
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);
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);
835 $dblink_window->vbox->pack_start( $hbox, $false, $false, 5);
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);
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);
847 $bbox = new Gtk
::HButtonBox
();
848 $bbox->set_layout("end");
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
;
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
;
867 sub store_current_dblink
869 if ((defined($seq[$current])) && ($seq[$current]->annotation->each_DBLink))
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) );
882 sub update_dblink_window
885 $dblink_window->show_all() if (defined($show_me));
887 $dblink_clist->freeze();
888 if (!defined($seq[$current]))
890 $dblink_clist->clear();
891 $dblink_clist->thaw();
892 foreach (@dblink_entry) { $_->set_text(""); }
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("",""); }
902 for(my $i=0;$i<@dblinks;$i++)
904 $dblink_clist->set_text($i,0,$dblinks[$i]->primary_id);
905 $dblink_clist->set_text($i,1,$dblinks[$i]->database);
907 # redraw text widgets
908 foreach (@dblink_entry) { $_->set_text(""); }
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);
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();
926 sub init_reference_window
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);
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' );
941 # Create the CList. For this example we use 2 columns
942 $ref_clist = new_with_titles Gtk
::CList
( "Medline","Title","Authors" );
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
;
951 &update_reference_window
;
954 # It isn't necessary to shadow the border, but it looks nice :)
955 $ref_clist->set_shadow_type( 'out' );
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 );
964 # Add the CList widget to the vertical box
965 $scrolled_window->add( $ref_clist );
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
975 # next ref button handler
976 sub { return if (!defined($seq[$current]));
977 &store_current_reference
;
979 if ($current_ref <((scalar $seq[$current]->annotation->each_Reference)-1));
980 &update_reference_window
;
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
;
992 if ($current_ref > 0);
993 &update_reference_window
;
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
;
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
;
1021 $ref_window->vbox->pack_start( $bbox, $false, $false, 0);
1023 # horizontal box containing primary_id & optional_id entries
1025 $hbox = new Gtk
::HBox
( $true, 10 );
1026 $hbox->border_width( 1 );
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);
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);
1040 $hbox = new Gtk
::HBox
( $true, 10 );
1041 $hbox->border_width( 1 );
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);
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);
1054 $ref_window->vbox->pack_start( $hbox, $false, $false, 5);
1057 $hbox = new Gtk
::HBox
( $false, 10 );
1058 $hbox->border_width( 1 );
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);
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);
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);
1076 $ref_window->vbox->pack_start( $hbox, $false, $false, 5);
1079 $bbox = new Gtk
::HButtonBox
();
1080 $bbox->set_layout("end");
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
;
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
;
1099 sub store_current_reference
1101 if ((defined($seq[$current])) && ($seq[$current]->annotation->each_Reference))
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) );
1120 sub update_reference_window
1123 $ref_window->show_all() if (defined($show_me));
1125 $ref_clist->freeze();
1126 if (!defined($seq[$current]))
1128 $ref_clist->clear();
1130 foreach (@ref_entry) { $_->set_text(""); }
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("","",""); }
1140 for(my $i=0;$i<@refs;$i++)
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);
1149 # redraw text widgets
1150 foreach (@ref_entry) { $_->set_text(""); }
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);
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);
1171 sub 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
1185 gSequence is cool! :-)\n(this text is to be written...)
1187 $vbox->pack_start($tbox,1,1,1);
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);
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);
1208 sub init_feature_window
1210 $current_feature_item = 0;
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);
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 );
1223 # Create a VBox for the Entry and Tree Scrolled Window
1224 my $vbox = new Gtk
::VBox
( $false, 0 );
1225 $pane->add1( $vbox );
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' );
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 );
1238 # add stuff to the vbox
1240 my $hbox = new Gtk
::HBox
( $true, 10 );
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);
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);
1252 $vbox->pack_start( $hbox, $false, $false, 5);
1254 $hbox = new Gtk
::HBox
( $true, 10 );
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);
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);
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);
1275 $vbox->pack_start( $hbox, $false, $false, 5);
1277 $feature_entry[2] = new Gtk
::Entry
();
1278 $frame = new Gtk
::Frame
("Description");
1279 $frame->add($feature_entry[2]);
1281 $vbox->pack_start( $frame, $false, $false, 5);
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);
1301 $current_feature_item->deselect()
1302 if ($current_feature_item);
1303 $item_new->select();
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 );
1323 $current_feature_item->deselect();
1324 $current_feature_item->expand();
1325 $item_new->select();
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
};
1335 for(my $i=0;$i<@
$flist;$i++) {
1336 $pos=$i if $$flist[$i]==$current_feature_item->get_user_data();
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;
1344 $vbox->pack_end( $bbox, $false, $false, 0);
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' );
1352 $bbox = new Gtk
::HButtonBox
();
1353 $bbox->set_layout("end");
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
;
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
;
1372 # Callback for expanding tree
1373 sub expand_feature_tree
1375 my ( $item, $subtree ) = @_;
1376 my ($feature,$subfeature,$item_new,$new_subtree);
1377 $feature = $item->get_user_data();
1379 foreach $subfeature ($feature->sub_SeqFeature)
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 );
1387 if ( $subfeature->sub_SeqFeature )
1389 $new_subtree = new Gtk
::Tree
();
1390 $item_new->set_subtree( $new_subtree );
1391 $item_new->signal_connect( 'expand',
1392 \
&expand_feature_tree
,
1394 $item_new->signal_connect( 'collapse', \
&collapse_feature_tree
);
1396 $item_new->expand();
1401 # Callback for collapsing tree
1402 sub collapse_feature_tree
1406 my $subtree = new Gtk
::Tree
();
1408 $item->remove_subtree();
1409 $item->set_subtree( $subtree );
1410 $item->signal_connect( 'expand', \
&expand_feature_tree
, $subtree );
1414 sub store_current_feature
1416 if ((defined($seq[$current])) && ($seq[$current]->top_SeqFeatures) && ($current_feature_item))
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"))
1423 $current_feature->remove_tag("description");
1424 $current_feature->add_tag_value("description",
1425 $feature_entry[2]->get_chars(0,-1));
1427 $current_feature->start($feature_spinner[0]->get_value_as_int());
1428 $current_feature->end($feature_spinner[1]->get_value_as_int());
1430 ($current_feature_item->children)[0]->set($current_feature->primary_tag);
1434 sub select_feature_item
1437 &store_current_feature
;
1438 $current_feature_item->deselect()
1439 if $current_feature_item;
1440 $current_feature_item = $widget;
1441 &update_feature_paned2
;
1444 sub update_feature_paned2
1446 $feature_entry[0]->set_text("");
1447 $feature_entry[1]->set_text("");
1448 $feature_entry[2]->set_text("");
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,
1459 $seq[$current]->length-1,
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,
1469 $seq[$current]->length-1,
1474 $feature_spinner[1]->set_adjustment($adj);
1475 $feature_spinner[1]->set_value($current_feature->end);
1476 $feature_spinner[1]->show_all();
1479 sub select_feature_region
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;
1487 sub update_feature_window
1490 $feature_window->show_all() if (defined($show_me));
1492 $feature_tree->clear_items(0,-1);
1493 if (!defined($seq[$current]))
1495 &update_feature_paned2
;
1499 my ($item_new,$new_subtree);
1500 foreach ($seq[$current]->top_SeqFeatures)
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 )
1508 $new_subtree = new Gtk
::Tree
();
1509 $item_new->set_subtree( $new_subtree );
1510 $item_new->signal_connect( 'expand',
1511 \
&expand_feature_tree
,
1513 $item_new->signal_connect( 'collapse', \
&collapse_feature_tree
);
1515 $item_new->expand();
1517 $feature_tree->select_item($current_feature_item)
1518 if $current_feature_item;
1519 $feature_tree->show_all();
1521 &update_feature_paned2
;
1528 sub update_pref_window
1530 $pref_window->show_all();
1533 sub init_pref_window
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 );
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' );
1545 my $main_vbox = new Gtk
::VBox
($false,10);
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);
1551 $main_vbox->pack_start($frame,$false,$false,10);
1553 $notebook->append_page( $main_vbox, $label );
1555 my $hbox = new Gtk
::HBox
($false,0);
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);
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);
1567 $vbox->pack_start( $hbox, $false, $false, 0);
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);
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);
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);
1584 $frame = new Gtk
::Frame
("Remote DBs");
1585 $hbox = new Gtk
::HBox
($false,10);
1587 $main_vbox->pack_start($frame,$false,$false,10);
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);
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);
1599 $notebook->set_page( 0 );
1601 my $bbox = new Gtk
::HButtonBox
();
1602 $bbox->set_layout("end");
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();
1612 $button = new Gtk
::Button
( "Close" );
1613 $bbox->add( $button );
1614 $button->signal_connect("clicked",
1615 # close button handler
1616 sub{ $pref_window->hide();
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();