Reload alignment
[jalview.git] / src / jalview / gui / AlignFrame.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Softwarechang
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19 package jalview.gui;
20
21 import java.beans.*;
22 import java.io.*;
23 import java.util.*;
24
25 import java.awt.*;
26 import java.awt.datatransfer.*;
27 import java.awt.event.*;
28 import java.awt.print.*;
29 import javax.swing.*;
30
31 import jalview.analysis.*;
32 import jalview.datamodel.*;
33 import jalview.io.*;
34 import jalview.jbgui.*;
35 import jalview.schemes.*;
36 import jalview.commands.*;
37 import jalview.ws.*;
38 import java.awt.dnd.*;
39
40 /**
41  * DOCUMENT ME!
42  *
43  * @author $author$
44  * @version $Revision$
45  */
46 public class AlignFrame extends GAlignFrame implements DropTargetListener
47 {
48   /** DOCUMENT ME!! */
49   public static final int DEFAULT_WIDTH = 700;
50
51   /** DOCUMENT ME!! */
52   public static final int DEFAULT_HEIGHT = 500;
53   public AlignmentPanel alignPanel;
54
55   AlignViewport viewport;
56
57   Vector alignPanels = new Vector();
58
59
60   /** DOCUMENT ME!! */
61   public String currentFileFormat = null;
62
63   public String fileName = null;
64
65   private int treeCount = 0;
66
67   /**
68    * Creates a new AlignFrame object.
69    *
70    * @param al DOCUMENT ME!
71    */
72   public AlignFrame(AlignmentI al, int width, int height)
73   {
74     this(al, null, width, height);
75   }
76
77
78   /**
79    * new alignment window with hidden columns
80    * @param al AlignmentI
81    * @param hiddenColumns ColumnSelection or null
82    */
83   public AlignFrame(AlignmentI al, ColumnSelection hiddenColumns,
84                     int width, int height)
85   {
86     this.setSize(width, height);
87     viewport = new AlignViewport(al, hiddenColumns);
88
89     alignPanel = new AlignmentPanel(this, viewport);
90
91     if(al.getDataset()==null)
92     {
93       al.setDataset(null);
94     }
95
96     addAlignmentPanel(alignPanel, true);
97     init();
98   }
99
100   /**
101    * Make a new AlignFrame from exisiting alignmentPanels
102    * @param ap AlignmentPanel
103    * @param av AlignViewport
104    */
105   public AlignFrame(AlignmentPanel ap)
106   {
107     viewport = ap.av;
108     alignPanel = ap;
109     addAlignmentPanel(ap, false);
110     init();
111   }
112
113   void init()
114   {
115     this.setDropTarget(new java.awt.dnd.DropTarget(this, this));
116
117     if (viewport.conservation == null)
118     {
119       BLOSUM62Colour.setEnabled(false);
120       conservationMenuItem.setEnabled(false);
121       modifyConservation.setEnabled(false);
122     //  PIDColour.setEnabled(false);
123     //  abovePIDThreshold.setEnabled(false);
124     //  modifyPID.setEnabled(false);
125     }
126
127     String sortby = jalview.bin.Cache.getDefault("SORT_ALIGNMENT", "No sort");
128
129     if (sortby.equals("Id"))
130       sortIDMenuItem_actionPerformed(null);
131     else if (sortby.equals("Pairwise Identity"))
132       sortPairwiseMenuItem_actionPerformed(null);
133
134     if (Desktop.desktop != null)
135    {
136      addServiceListeners();
137      setGUINucleotide(viewport.alignment.isNucleotide());
138    }
139
140    setMenusFromViewport(viewport);
141
142    if (viewport.wrapAlignment)
143    {
144      wrapMenuItem_actionPerformed(null);
145    }
146
147    addKeyListener();
148
149
150   }
151
152   void addKeyListener()
153   {
154       final AlignFrame af = this;
155       addKeyListener(new KeyAdapter()
156       {
157         public void keyPressed(KeyEvent evt)
158         {
159           if (viewport.cursorMode
160               && evt.getKeyCode() >= KeyEvent.VK_0
161               && evt.getKeyCode() <= KeyEvent.VK_9)
162           {
163             alignPanel.seqPanel.numberPressed(evt.getKeyChar());
164           }
165
166           switch (evt.getKeyCode())
167           {
168             case KeyEvent.VK_V:
169               if (!evt.isControlDown())
170               {
171                 AlignmentPanel newap =
172                     new Jalview2XML().copyAlignPanel(alignPanel, true);
173
174                 if(viewport.viewName==null)
175                   viewport.viewName="View 1";
176
177                 newap.av.historyList = viewport.historyList;
178                 newap.av.redoList = viewport.redoList;
179                 newap.av.viewName = "View " +
180                     (Desktop.getViewCount(viewport.getSequenceSetId())+1);
181
182                 addAlignmentPanel(newap, false);
183
184                 tabbedPane.setSelectedIndex(tabbedPane.getTabCount()-1);
185
186               }
187               break;
188             case KeyEvent.VK_G:
189               Desktop.instance.gatherViews(af);
190               break;
191
192             case KeyEvent.VK_X:
193               if (!evt.isControlDown())
194               {
195                 Desktop.instance.explodeViews(af);
196               }
197               break;
198
199
200             case 27: // escape key
201               deselectAllSequenceMenuItem_actionPerformed(null);
202
203               break;
204
205             case KeyEvent.VK_DOWN:
206               if (viewport.cursorMode)
207               {
208                 alignPanel.seqPanel.moveCursor(0, 1);
209               }
210               else
211                 moveSelectedSequences(false);
212               break;
213
214             case KeyEvent.VK_UP:
215               if (viewport.cursorMode)
216               {
217                 alignPanel.seqPanel.moveCursor(0, -1);
218               }
219               else
220                 moveSelectedSequences(true);
221               break;
222
223             case KeyEvent.VK_LEFT:
224               if (viewport.cursorMode)
225               {
226                 alignPanel.seqPanel.moveCursor( -1, 0);
227               }
228               break;
229
230             case KeyEvent.VK_RIGHT:
231               if (viewport.cursorMode)
232               {
233                 alignPanel.seqPanel.moveCursor(1, 0);
234               }
235               break;
236
237             case KeyEvent.VK_SPACE:
238               if (viewport.cursorMode)
239               {
240                 alignPanel.seqPanel.insertGapAtCursor(evt.isControlDown()
241                                            || evt.isShiftDown()
242                                            || evt.isAltDown());
243               }
244               break;
245
246             case KeyEvent.VK_DELETE:
247             case KeyEvent.VK_BACK_SPACE:
248               if (!viewport.cursorMode)
249               {
250                 cut_actionPerformed(null);
251               }
252               else
253                 alignPanel.seqPanel.deleteGapAtCursor(evt.isControlDown()
254                                            || evt.isShiftDown()
255                                            || evt.isAltDown());
256
257               break;
258
259             case KeyEvent.VK_S:
260               if (viewport.cursorMode)
261               {
262                 alignPanel.seqPanel.setCursorRow();
263               }
264               break;
265             case KeyEvent.VK_C:
266               if (viewport.cursorMode && !evt.isControlDown())
267               {
268                 alignPanel.seqPanel.setCursorColumn();
269               }
270               break;
271             case KeyEvent.VK_P:
272               if (viewport.cursorMode)
273               {
274                 alignPanel.seqPanel.setCursorPosition();
275               }
276               break;
277
278             case KeyEvent.VK_ENTER:
279             case KeyEvent.VK_COMMA:
280               if (viewport.cursorMode)
281               {
282                 alignPanel.seqPanel.setCursorRowAndColumn();
283               }
284               break;
285
286             case KeyEvent.VK_Q:
287               if (viewport.cursorMode)
288               {
289                 alignPanel.seqPanel.setSelectionAreaAtCursor(true);
290               }
291               break;
292             case KeyEvent.VK_M:
293               if (viewport.cursorMode)
294               {
295                 alignPanel.seqPanel.setSelectionAreaAtCursor(false);
296               }
297               break;
298
299             case KeyEvent.VK_F2:
300               viewport.cursorMode = !viewport.cursorMode;
301               statusBar.setText("Keyboard editing mode is " +
302                                            (viewport.cursorMode ? "on" : "off"));
303               if (viewport.cursorMode)
304               {
305                 alignPanel.seqPanel.seqCanvas.cursorX = viewport.startRes;
306                 alignPanel.seqPanel.seqCanvas.cursorY = viewport.startSeq;
307               }
308               alignPanel.seqPanel.seqCanvas.repaint();
309               break;
310
311             case KeyEvent.VK_F1:
312               try
313               {
314                 ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
315                 java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
316                 javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
317
318                 javax.help.HelpBroker hb = hs.createHelpBroker();
319                 hb.setCurrentID("home");
320                 hb.setDisplayed(true);
321               }
322               catch (Exception ex)
323               {
324                 ex.printStackTrace();
325               }
326               break
327                   ;
328             case KeyEvent.VK_H:
329             {
330               boolean toggleSeqs = !evt.isControlDown();
331               boolean toggleCols = !evt.isShiftDown();
332
333               boolean hide = false;
334
335               SequenceGroup sg = viewport.getSelectionGroup();
336               if (toggleSeqs)
337               {
338                 if (sg != null && sg.getSize(false) != viewport.alignment.getHeight())
339                 {
340                   hideSelSequences_actionPerformed(null);
341                   hide = true;
342                 }
343                 else if (! (toggleCols && viewport.colSel.getSelected().size() > 0))
344                   showAllSeqs_actionPerformed(null);
345               }
346
347               if (toggleCols)
348               {
349                 if (viewport.colSel.getSelected().size() > 0)
350                 {
351                   hideSelColumns_actionPerformed(null);
352                   if (!toggleSeqs)
353                     viewport.selectionGroup = sg;
354                 }
355                 else if (!hide)
356                   showAllColumns_actionPerformed(null);
357               }
358               break;
359             }
360             case KeyEvent.VK_PAGE_UP:
361               if (viewport.wrapAlignment)
362                 alignPanel.scrollUp(true);
363               else
364                 alignPanel.setScrollValues(viewport.startRes,
365                                            viewport.startSeq
366                                            - viewport.endSeq + viewport.startSeq);
367               break;
368             case KeyEvent.VK_PAGE_DOWN:
369               if (viewport.wrapAlignment)
370                 alignPanel.scrollUp(false);
371               else
372                 alignPanel.setScrollValues(viewport.startRes,
373                                            viewport.startSeq
374                                            + viewport.endSeq - viewport.startSeq);
375               break;
376           }
377         }
378       });
379   }
380
381
382   public void addAlignmentPanel(final AlignmentPanel ap,
383                                 boolean newPanel)
384   {
385     ap.alignFrame = this;
386
387     alignPanels.addElement(ap);
388
389     int aSize = alignPanels.size();
390
391     tabbedPane.setVisible(aSize>1 || ap.av.viewName!=null);
392
393     if (aSize == 1 && ap.av.viewName==null)
394     {
395       this.getContentPane().add(ap, BorderLayout.CENTER);
396     }
397     else
398     {
399       if (aSize == 2)
400       {
401         AlignmentPanel first = (AlignmentPanel) alignPanels.firstElement();
402         tabbedPane.addTab(first.av.viewName==null?"Original":first.av.viewName,first);
403
404         this.getContentPane().add(tabbedPane, BorderLayout.CENTER);
405       }
406
407       tabbedPane.addTab(ap.av.viewName==null?"Original":ap.av.viewName, ap);
408
409       ap.setVisible(false);
410     }
411
412     if(newPanel)
413     {
414       ap.av.updateConsensus(ap);
415       ap.av.updateConservation(ap);
416     }
417   }
418
419
420   public AlignViewport getViewport()
421   {
422     return viewport;
423   }
424
425   /* Set up intrinsic listeners for dynamically generated GUI bits. */
426   private void addServiceListeners()
427   {
428     final java.beans.PropertyChangeListener thisListener;
429     // Do this once to get current state
430     BuildWebServiceMenu();
431     Desktop.discoverer.addPropertyChangeListener(
432         thisListener = new java.beans.PropertyChangeListener()
433     {
434       public void propertyChange(PropertyChangeEvent evt)
435       {
436         // System.out.println("Discoverer property change.");
437         if (evt.getPropertyName().equals("services"))
438         {
439           // System.out.println("Rebuilding web service menu");
440           BuildWebServiceMenu();
441         }
442       }
443     });
444
445     addInternalFrameListener(new javax.swing.event.
446                              InternalFrameAdapter()
447     {
448       public void internalFrameClosed(
449           javax.swing.event.InternalFrameEvent evt)
450       {
451         // System.out.println("deregistering discoverer listener");
452         Desktop.discoverer.removePropertyChangeListener(thisListener);
453         closeMenuItem_actionPerformed(null);
454       }
455       ;
456     });
457   }
458
459   public void setGUINucleotide(boolean nucleotide)
460   {
461     showTranslation.setVisible( nucleotide );
462     conservationMenuItem.setEnabled( !nucleotide );
463     modifyConservation.setEnabled(   !nucleotide );
464
465     //Remember AlignFrame always starts as protein
466     if(!nucleotide)
467     {
468       calculateMenu.remove(calculateMenu.getItemCount()-2);
469     }
470   }
471
472   /**
473    * Need to call this method when tabs are selected for multiple views,
474    * or when loading from Jalview2XML.java
475    * @param av AlignViewport
476    */
477   void setMenusFromViewport(AlignViewport av)
478   {
479     colourTextMenuItem.setSelected(av.showColourText);
480     abovePIDThreshold.setSelected(av.getAbovePIDThreshold());
481     conservationMenuItem.setSelected(av.getConservationSelected());
482     seqLimits.setSelected(av.getShowJVSuffix());
483     renderGapsMenuItem.setSelected(av.renderGaps);
484     wrapMenuItem.setSelected(av.wrapAlignment);
485     annotationPanelMenuItem.setState(av.showAnnotation);
486     viewBoxesMenuItem.setSelected(av.showBoxes);
487     viewTextMenuItem.setSelected(av.showText);
488
489     setColourSelected(ColourSchemeProperty.
490                       getColourName(av.getGlobalColourScheme()));
491
492     showSeqFeatures.setSelected(av.showSequenceFeatures);
493     hiddenMarkers.setState(av.showHiddenMarkers);
494     applyToAllGroups.setState(av.colourAppliesToAllGroups);
495     smoothFont.setState(av.antiAlias);
496
497     updateEditMenuBar();
498   }
499
500
501   Hashtable progressBars;
502   public void setProgressBar(String message, long id)
503   {
504     if(progressBars == null)
505       progressBars = new Hashtable();
506
507     JPanel progressPanel;
508     GridLayout layout = (GridLayout) statusPanel.getLayout();
509     if(progressBars.get( new Long(id) )!=null)
510      {
511        progressPanel = (JPanel)progressBars.get( new Long(id) );
512        statusPanel.remove(progressPanel);
513        progressBars.remove( progressPanel );
514        progressPanel = null;
515        if(message!=null)
516          statusBar.setText(message);
517
518        layout.setRows(layout.getRows() - 1);
519      }
520     else
521     {
522       progressPanel = new JPanel(new BorderLayout(10, 5));
523
524       JProgressBar progressBar = new JProgressBar();
525       progressBar.setIndeterminate(true);
526
527       progressPanel.add(new JLabel(message), BorderLayout.WEST);
528       progressPanel.add(progressBar, BorderLayout.CENTER);
529
530       layout.setRows(layout.getRows() + 1);
531       statusPanel.add(progressPanel);
532
533       progressBars.put(new Long(id), progressPanel);
534     }
535
536     validate();
537   }
538
539
540
541
542   /*
543    Added so Castor Mapping file can obtain Jalview Version
544   */
545   public String getVersion()
546   {
547     return  jalview.bin.Cache.getProperty("VERSION");
548   }
549
550   public FeatureRenderer getFeatureRenderer()
551   {
552     return alignPanel.seqPanel.seqCanvas.getFeatureRenderer();
553   }
554
555
556   public void fetchSequence_actionPerformed(ActionEvent e)
557   {
558     new SequenceFetcher(this);
559   }
560
561   public void addFromFile_actionPerformed(ActionEvent e)
562   {
563     Desktop.instance.inputLocalFileMenuItem_actionPerformed(viewport);
564   }
565
566   public void reload_actionPerformed(ActionEvent e)
567   {
568     if(fileName!=null)
569     {
570       viewport.alignment.deleteAllGroups();
571       while (viewport.alignment.getHeight() > 0)
572       {
573         viewport.alignment.deleteSequence(0);
574       }
575
576       FileLoader loader = new FileLoader();
577       loader.LoadFile(viewport, fileName, "File", currentFileFormat);
578
579     }
580   }
581
582
583   public void addFromText_actionPerformed(ActionEvent e)
584   {
585     Desktop.instance.inputTextboxMenuItem_actionPerformed(viewport);
586   }
587
588   public void addFromURL_actionPerformed(ActionEvent e)
589   {
590     Desktop.instance.inputURLMenuItem_actionPerformed(viewport);
591   }
592
593
594   public void save_actionPerformed(ActionEvent e)
595   {
596     if(fileName==null || currentFileFormat==null)
597       saveAs_actionPerformed(null);
598     else
599       saveAlignment(fileName, currentFileFormat);
600   }
601
602   /**
603    * DOCUMENT ME!
604    *
605    * @param e DOCUMENT ME!
606    */
607   public void saveAs_actionPerformed(ActionEvent e)
608   {
609     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
610         getProperty( "LAST_DIRECTORY"),
611         new String[]
612         { "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc","jar" },
613         new String[]
614         { "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview" },
615         currentFileFormat,
616         false);
617
618
619     chooser.setFileView(new JalviewFileView());
620     chooser.setDialogTitle("Save Alignment to file");
621     chooser.setToolTipText("Save");
622
623     int value = chooser.showSaveDialog(this);
624
625     if (value == JalviewFileChooser.APPROVE_OPTION)
626     {
627         currentFileFormat = chooser.getSelectedFormat();
628         if (currentFileFormat == null)
629         {
630           JOptionPane.showInternalMessageDialog(Desktop.desktop,
631                                                 "You must select a file format before saving!",
632                                                 "File format not specified",
633                                                 JOptionPane.WARNING_MESSAGE);
634           value = chooser.showSaveDialog(this);
635           return;
636         }
637
638         fileName = chooser.getSelectedFile().getPath();
639
640       jalview.bin.Cache.setProperty("DEFAULT_FILE_FORMAT",
641                                     currentFileFormat);
642
643       jalview.bin.Cache.setProperty("LAST_DIRECTORY", fileName);
644
645       saveAlignment(fileName, currentFileFormat);
646     }
647   }
648
649   public boolean saveAlignment(String file, String format)
650   {
651     if (format.equalsIgnoreCase("Jalview"))
652     {
653       String shortName = title;
654
655       if (shortName.indexOf(java.io.File.separatorChar) > -1)
656       {
657         shortName = shortName.substring(shortName.lastIndexOf(
658             java.io.File.separatorChar) + 1);
659       }
660
661       new Jalview2XML().SaveAlignment(this, file, shortName);
662
663       statusBar.setText("Successfully saved to file: "
664                           +fileName+" in "
665                           +format +" format.");
666
667
668       // USE Jalview2XML to save this file
669       return true;
670     }
671     else
672     {
673
674       String[] omitHidden = null;
675
676       if (viewport.hasHiddenColumns)
677       {
678         int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
679             "The Alignment contains hidden columns."
680             + "\nDo you want to save only the visible alignment?",
681             "Save / Omit Hidden Columns",
682             JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
683
684         if (reply == JOptionPane.YES_OPTION)
685           omitHidden = viewport.getViewAsString(false);
686       }
687
688       String output = new FormatAdapter().formatSequences(
689           format,
690           viewport.alignment.getSequencesArray(),
691           omitHidden);
692
693       if (output == null)
694       {
695         return false;
696       }
697
698       try
699       {
700         java.io.PrintWriter out = new java.io.PrintWriter(
701             new java.io.FileWriter(file));
702
703         out.print(output);
704         out.close();
705         this.setTitle(file);
706         statusBar.setText("Successfully saved to file: "
707                           +fileName+" in "
708                           +format +" format.");
709         return true;
710       }
711       catch (Exception ex)
712       {
713         ex.printStackTrace();
714       }
715     }
716     return false;
717   }
718
719   /**
720    * DOCUMENT ME!
721    *
722    * @param e DOCUMENT ME!
723    */
724   protected void outputText_actionPerformed(ActionEvent e)
725   {
726     String [] omitHidden = null;
727
728     if(viewport.hasHiddenColumns)
729     {
730       int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
731           "The Alignment contains hidden columns."
732       +"\nDo you want to output only the visible alignment?",
733       "Save / Omit Hidden Columns",
734       JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
735
736       if(reply==JOptionPane.YES_OPTION)
737       {
738         omitHidden = viewport.getViewAsString(false);
739       }
740     }
741
742     CutAndPasteTransfer cap = new CutAndPasteTransfer();
743     Desktop.addInternalFrame(cap,
744                              "Alignment output - " + e.getActionCommand(), 600,
745                              500);
746
747
748     cap.setText(new FormatAdapter().formatSequences(
749         e.getActionCommand(),
750         viewport.alignment.getSequencesArray(),
751         omitHidden));
752   }
753
754   /**
755    * DOCUMENT ME!
756    *
757    * @param e DOCUMENT ME!
758    */
759   protected void htmlMenuItem_actionPerformed(ActionEvent e)
760   {
761     new HTMLOutput(viewport,
762                    alignPanel.seqPanel.seqCanvas.getSequenceRenderer(),
763         alignPanel.seqPanel.seqCanvas.getFeatureRenderer());
764   }
765
766   public void createImageMap(File file, String image)
767   {
768     alignPanel.makePNGImageMap(file, image);
769   }
770
771   /**
772    * DOCUMENT ME!
773    *
774    * @param e DOCUMENT ME!
775    */
776   public void createPNG(File f)
777   {
778     alignPanel.makePNG(f);
779   }
780
781   /**
782    * DOCUMENT ME!
783    *
784    * @param e DOCUMENT ME!
785    */
786   public void createEPS(File f)
787   {
788     alignPanel.makeEPS(f);
789   }
790
791   /**
792    * DOCUMENT ME!
793    *
794    * @param e DOCUMENT ME!
795    */
796   public void printMenuItem_actionPerformed(ActionEvent e)
797   {
798     //Putting in a thread avoids Swing painting problems
799     PrintThread thread = new PrintThread();
800     thread.start();
801   }
802
803   public void exportFeatures_actionPerformed(ActionEvent e)
804   {
805     new AnnotationExporter().exportFeatures(alignPanel);
806   }
807
808
809   public void exportAnnotations_actionPerformed(ActionEvent e)
810   {
811     new AnnotationExporter().exportAnnotations(
812       alignPanel,
813       viewport.alignment.getAlignmentAnnotation()
814         );
815   }
816
817
818   public void associatedData_actionPerformed(ActionEvent e)
819   {
820     // Pick the tree file
821     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
822         getProperty(
823             "LAST_DIRECTORY"));
824     chooser.setFileView(new JalviewFileView());
825     chooser.setDialogTitle("Load Jalview Annotations or Features File");
826     chooser.setToolTipText("Load Jalview Annotations / Features file");
827
828     int value = chooser.showOpenDialog(null);
829
830     if (value == JalviewFileChooser.APPROVE_OPTION)
831     {
832       String choice = chooser.getSelectedFile().getPath();
833       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
834       loadJalviewDataFile(choice);
835     }
836
837   }
838
839
840   /**
841    * DOCUMENT ME!
842    *
843    * @param e DOCUMENT ME!
844    */
845   public void closeMenuItem_actionPerformed(ActionEvent e)
846   {
847     try
848     {
849       if(alignPanels!=null)
850       {
851         for (int i = 0; i < alignPanels.size(); i++)
852         {
853           AlignmentPanel ap = (AlignmentPanel) alignPanels.elementAt(i);
854           PaintRefresher.RemoveComponent(ap.seqPanel.seqCanvas);
855           PaintRefresher.RemoveComponent(ap.idPanel.idCanvas);
856           PaintRefresher.RemoveComponent(ap);
857         }
858       //  alignPanels = null;
859       }
860     //  else
861      //   System.out.println("null one here");
862
863     //  alignPanel = null;
864     //  viewport = null;
865
866       this.setClosed(true);
867     }
868     catch (Exception ex)
869     {
870       ex.printStackTrace();
871     }
872   }
873
874
875   /**
876    * DOCUMENT ME!
877    */
878   void updateEditMenuBar()
879   {
880
881     if (viewport.historyList.size() > 0)
882     {
883       undoMenuItem.setEnabled(true);
884       CommandI command = (CommandI) viewport.historyList.peek();
885       undoMenuItem.setText("Undo " + command.getDescription());
886     }
887     else
888     {
889       undoMenuItem.setEnabled(false);
890       undoMenuItem.setText("Undo");
891     }
892
893     if (viewport.redoList.size() > 0)
894     {
895       redoMenuItem.setEnabled(true);
896
897       CommandI command = (CommandI) viewport.redoList.peek();
898       redoMenuItem.setText("Redo " + command.getDescription());
899     }
900     else
901     {
902       redoMenuItem.setEnabled(false);
903       redoMenuItem.setText("Redo");
904     }
905   }
906
907
908   public void addHistoryItem(CommandI command)
909   {
910     if(command.getSize()>0)
911     {
912       viewport.historyList.push(command);
913       viewport.redoList.clear();
914       updateEditMenuBar();
915       viewport.hasHiddenColumns = viewport.colSel.getHiddenColumns() != null;
916     }
917   }
918
919
920
921   /**
922    * DOCUMENT ME!
923    *
924    * @param e DOCUMENT ME!
925    */
926   protected void undoMenuItem_actionPerformed(ActionEvent e)
927   {
928     CommandI command = (CommandI)viewport.historyList.pop();
929     viewport.redoList.push(command);
930     command.undoCommand();
931
932     viewport.hasHiddenColumns = viewport.colSel.getHiddenColumns() != null;
933     updateEditMenuBar();
934     viewport.firePropertyChange("alignment", null,
935                                 viewport.getAlignment().getSequences());
936   }
937
938   /**
939    * DOCUMENT ME!
940    *
941    * @param e DOCUMENT ME!
942    */
943   protected void redoMenuItem_actionPerformed(ActionEvent e)
944   {
945     CommandI command = (CommandI) viewport.redoList.pop();
946     viewport.historyList.push(command);
947     command.doCommand();
948     viewport.hasHiddenColumns = viewport.colSel.getHiddenColumns()!=null;
949
950     updateEditMenuBar();
951     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
952   }
953
954
955   /**
956    * DOCUMENT ME!
957    *
958    * @param up DOCUMENT ME!
959    */
960   public void moveSelectedSequences(boolean up)
961   {
962     SequenceGroup sg = viewport.getSelectionGroup();
963
964     if (sg == null)
965     {
966       return;
967     }
968
969     if (up)
970     {
971       for (int i = 1; i < viewport.alignment.getHeight(); i++)
972       {
973         SequenceI seq = viewport.alignment.getSequenceAt(i);
974
975         if (!sg.getSequences(false).contains(seq))
976         {
977           continue;
978         }
979
980         SequenceI temp = viewport.alignment.getSequenceAt(i - 1);
981
982         if (sg.getSequences(false).contains(temp))
983         {
984           continue;
985         }
986
987         viewport.alignment.getSequences().setElementAt(temp, i);
988         viewport.alignment.getSequences().setElementAt(seq, i - 1);
989       }
990     }
991     else
992     {
993       for (int i = viewport.alignment.getHeight() - 2; i > -1; i--)
994       {
995         SequenceI seq = viewport.alignment.getSequenceAt(i);
996
997         if (!sg.getSequences(false).contains(seq))
998         {
999           continue;
1000         }
1001
1002         SequenceI temp = viewport.alignment.getSequenceAt(i + 1);
1003
1004         if (sg.getSequences(false).contains(temp))
1005         {
1006           continue;
1007         }
1008
1009         viewport.alignment.getSequences().setElementAt(temp, i);
1010         viewport.alignment.getSequences().setElementAt(seq, i + 1);
1011       }
1012     }
1013
1014     alignPanel.repaint();
1015   }
1016
1017
1018
1019   /**
1020    * DOCUMENT ME!
1021    *
1022    * @param e DOCUMENT ME!
1023    */
1024   protected void copy_actionPerformed(ActionEvent e)
1025   {
1026     System.gc();
1027     if (viewport.getSelectionGroup() == null)
1028     {
1029       return;
1030     }
1031
1032     SequenceI [] seqs = viewport.getSelectionAsNewSequence();
1033     String[] omitHidden = null;
1034
1035     if (viewport.hasHiddenColumns)
1036     {
1037       omitHidden = viewport.getViewAsString(true);
1038     }
1039
1040     String output = new FormatAdapter().formatSequences(
1041         "Fasta",
1042         seqs,
1043         omitHidden);
1044
1045     StringSelection ss = new StringSelection(output);
1046
1047     try
1048     {
1049       //Its really worth setting the clipboard contents
1050       //to empty before setting the large StringSelection!!
1051       Toolkit.getDefaultToolkit().getSystemClipboard()
1052           .setContents(new StringSelection(""), null);
1053
1054       Toolkit.getDefaultToolkit().getSystemClipboard()
1055           .setContents(ss, Desktop.instance);
1056     }
1057     catch (OutOfMemoryError er)
1058     {
1059       er.printStackTrace();
1060       javax.swing.SwingUtilities.invokeLater(new Runnable()
1061           {
1062             public void run()
1063             {
1064               javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop,
1065                   "Out of memory copying region!!"
1066                   +
1067                   "\nSee help files for increasing Java Virtual Machine memory."
1068                   , "Out of memory",
1069                   javax.swing.JOptionPane.WARNING_MESSAGE);
1070             }
1071           });
1072
1073       return;
1074     }
1075
1076     Vector hiddenColumns = null;
1077     if(viewport.hasHiddenColumns)
1078     {
1079       hiddenColumns =new Vector();
1080       int hiddenOffset = viewport.getSelectionGroup().getStartRes();
1081       for(int i=0; i<viewport.getColumnSelection().getHiddenColumns().size(); i++)
1082       {
1083         int[] region = (int[])
1084             viewport.getColumnSelection().getHiddenColumns().elementAt(i);
1085
1086         hiddenColumns.addElement(new int[]{region[0]-hiddenOffset,
1087                           region[1]-hiddenOffset});
1088       }
1089     }
1090
1091
1092
1093     Desktop.jalviewClipboard = new Object[]{ seqs,
1094         viewport.alignment.getDataset(),
1095         hiddenColumns};
1096     statusBar.setText("Copied "+seqs.length+" sequences to clipboard.");
1097   }
1098
1099   /**
1100    * DOCUMENT ME!
1101    *
1102    * @param e DOCUMENT ME!
1103    */
1104   protected void pasteNew_actionPerformed(ActionEvent e)
1105   {
1106     paste(true);
1107   }
1108
1109   /**
1110    * DOCUMENT ME!
1111    *
1112    * @param e DOCUMENT ME!
1113    */
1114   protected void pasteThis_actionPerformed(ActionEvent e)
1115   {
1116     paste(false);
1117   }
1118
1119   /**
1120    * DOCUMENT ME!
1121    *
1122    * @param newAlignment DOCUMENT ME!
1123    */
1124   void paste(boolean newAlignment)
1125   {
1126     try
1127     {
1128       Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
1129       Transferable contents = c.getContents(this);
1130
1131       if (contents == null)
1132       {
1133         return;
1134       }
1135
1136       String str, format;
1137       try
1138       {
1139         str = (String) contents.getTransferData(DataFlavor.stringFlavor);
1140         if (str.length() < 1)
1141           return;
1142
1143         format = new IdentifyFile().Identify(str, "Paste");
1144
1145       }
1146       catch (OutOfMemoryError er)
1147       {
1148         er.printStackTrace();
1149         javax.swing.SwingUtilities.invokeLater(new Runnable()
1150         {
1151           public void run()
1152           {
1153             javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop,
1154                 "Out of memory pasting sequences!!"
1155                 +
1156                 "\nSee help files for increasing Java Virtual Machine memory."
1157                 , "Out of memory",
1158                 javax.swing.JOptionPane.WARNING_MESSAGE);
1159           }
1160         });
1161
1162         return;
1163       }
1164
1165       SequenceI[] sequences;
1166
1167
1168      if(Desktop.jalviewClipboard!=null)
1169      {
1170        // The clipboard was filled from within Jalview, we must use the sequences
1171        // And dataset from the copied alignment
1172        sequences = (SequenceI[])Desktop.jalviewClipboard[0];
1173      }
1174      else
1175      {
1176        sequences = new FormatAdapter().readFile(str, "Paste", format);
1177      }
1178
1179      AlignmentI alignment = null;
1180
1181       if (newAlignment)
1182       {
1183           alignment = new Alignment(sequences);
1184
1185           if (Desktop.jalviewClipboard != null)
1186             alignment.setDataset( (Alignment) Desktop.jalviewClipboard[1]);
1187           else
1188             alignment.setDataset(null);
1189       }
1190       else
1191       {
1192         alignment = viewport.getAlignment();
1193
1194         //!newAlignment
1195         SequenceI [] newseqs = new SequenceI[sequences.length];
1196         for (int i = 0; i < sequences.length; i++)
1197         {
1198           newseqs[i] = new Sequence(sequences[i].getName(),
1199               sequences[i].getSequence(), sequences[i].getStart(),
1200               sequences[i].getEnd());
1201
1202           alignment.addSequence(newseqs[i]);
1203         }
1204
1205         /*
1206          //ADD HISTORY ITEM
1207          */
1208         addHistoryItem(new EditCommand(
1209             "Add sequences",
1210             EditCommand.PASTE,
1211             newseqs,
1212             0,
1213             alignment.getWidth(),
1214             alignment)
1215             );
1216
1217
1218         viewport.setEndSeq(alignment.getHeight());
1219         alignment.getWidth();
1220         viewport.firePropertyChange("alignment", null, alignment.getSequences());
1221       }
1222
1223
1224
1225       // Add any annotations attached to sequences
1226       for (int i = 0; i < sequences.length; i++)
1227      {
1228        if (sequences[i].getAnnotation() != null)
1229        {
1230          for (int a = 0; a < sequences[i].getAnnotation().length; a++)
1231          {
1232            AlignmentAnnotation newAnnot =
1233                new AlignmentAnnotation(
1234                    sequences[i].getAnnotation()[a].label,
1235                    sequences[i].getAnnotation()[a].description,
1236                    sequences[i].getAnnotation()[a].annotations,
1237                    sequences[i].getAnnotation()[a].graphMin,
1238                    sequences[i].getAnnotation()[a].graphMax,
1239                    sequences[i].getAnnotation()[a].graph);
1240
1241            sequences[i].getAnnotation()[a] = newAnnot;
1242            newAnnot.sequenceMapping = sequences[i].getAnnotation()[a].
1243                sequenceMapping;
1244            newAnnot.sequenceRef = sequences[i];
1245            newAnnot.adjustForAlignment();
1246            alignment.addAnnotation(newAnnot);
1247            alignment.setAnnotationIndex(newAnnot, a);
1248          }
1249
1250          alignPanel.annotationPanel.adjustPanelHeight();
1251        }
1252      }
1253
1254      if(newAlignment)
1255      {
1256        AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH, DEFAULT_HEIGHT);
1257        String newtitle = new String("Copied sequences");
1258
1259        if(Desktop.jalviewClipboard!=null && Desktop.jalviewClipboard[2]!=null)
1260          {
1261            Vector hc = (Vector)Desktop.jalviewClipboard[2];
1262            for(int i=0; i<hc.size(); i++)
1263            {
1264              int [] region = (int[]) hc.elementAt(i);
1265              af.viewport.hideColumns(region[0], region[1]);
1266            }
1267          }
1268
1269
1270        //>>>This is a fix for the moment, until a better solution is found!!<<<
1271        af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().transferSettings(
1272            alignPanel.seqPanel.seqCanvas.getFeatureRenderer());
1273
1274
1275        if (title.startsWith("Copied sequences"))
1276        {
1277          newtitle = title;
1278        }
1279        else
1280        {
1281          newtitle = newtitle.concat("- from " + title);
1282        }
1283
1284        Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH,
1285                                 DEFAULT_HEIGHT);
1286
1287      }
1288
1289
1290     }
1291     catch (Exception ex)
1292     {
1293       ex.printStackTrace();
1294         System.out.println("Exception whilst pasting: "+ex);
1295         // could be anything being pasted in here
1296     }
1297
1298
1299   }
1300
1301   /**
1302    * DOCUMENT ME!
1303    *
1304    * @param e DOCUMENT ME!
1305    */
1306   protected void cut_actionPerformed(ActionEvent e)
1307   {
1308     copy_actionPerformed(null);
1309     delete_actionPerformed(null);
1310   }
1311
1312   /**
1313    * DOCUMENT ME!
1314    *
1315    * @param e DOCUMENT ME!
1316    */
1317   protected void delete_actionPerformed(ActionEvent evt)
1318   {
1319
1320     SequenceGroup sg = viewport.getSelectionGroup();
1321     if (sg == null)
1322     {
1323       return;
1324     }
1325
1326     Vector seqs = new Vector();
1327     int cutLength = sg.getEndRes()-sg.getStartRes()+1;
1328     boolean seqsCut = false;
1329     SequenceI seq;
1330     for (int i = 0; i < sg.getSize(false); i++)
1331     {
1332       seq = sg.getSequenceAt(i);
1333       seqs.addElement(seq);
1334       if(seq.getLength()<=cutLength)
1335         seqsCut = true;
1336     }
1337
1338
1339    // If the cut affects all sequences, remove highlighted columns
1340    if (sg.getSize(false) == viewport.alignment.getHeight())
1341    {
1342      viewport.getColumnSelection().removeElements(sg.getStartRes(),
1343          sg.getEndRes() + 1);
1344    }
1345
1346
1347     SequenceI [] cut = new SequenceI[seqs.size()];
1348     for(int i=0; i<seqs.size(); i++)
1349       cut[i] = (SequenceI)seqs.elementAt(i);
1350
1351
1352     /*
1353     //ADD HISTORY ITEM
1354     */
1355     addHistoryItem(new EditCommand("Cut Sequences",
1356                                       EditCommand.CUT,
1357                                       cut,
1358                                       sg.getStartRes(),
1359                                       sg.getEndRes()-sg.getStartRes()+1,
1360                                       viewport.alignment));
1361
1362
1363     viewport.setSelectionGroup(null);
1364     viewport.alignment.deleteGroup(sg);
1365
1366     viewport.firePropertyChange("alignment", null,
1367                                   viewport.getAlignment().getSequences());
1368
1369     if (viewport.getAlignment().getHeight() < 1)
1370     {
1371       try
1372       {
1373         this.setClosed(true);
1374       }
1375       catch (Exception ex)
1376       {
1377       }
1378     }
1379   }
1380
1381   /**
1382    * DOCUMENT ME!
1383    *
1384    * @param e DOCUMENT ME!
1385    */
1386   protected void deleteGroups_actionPerformed(ActionEvent e)
1387   {
1388     viewport.alignment.deleteAllGroups();
1389     viewport.setSelectionGroup(null);
1390     PaintRefresher.Refresh(this, viewport.getSequenceSetId());
1391     alignPanel.repaint();
1392   }
1393
1394   /**
1395    * DOCUMENT ME!
1396    *
1397    * @param e DOCUMENT ME!
1398    */
1399   public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
1400   {
1401     SequenceGroup sg = new SequenceGroup();
1402
1403     for (int i = 0; i < viewport.getAlignment().getSequences().size();
1404          i++)
1405     {
1406       sg.addSequence(viewport.getAlignment().getSequenceAt(i), false);
1407     }
1408
1409     sg.setEndRes(viewport.alignment.getWidth() - 1);
1410     viewport.setSelectionGroup(sg);
1411     alignPanel.repaint();
1412     PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
1413   }
1414
1415   /**
1416    * DOCUMENT ME!
1417    *
1418    * @param e DOCUMENT ME!
1419    */
1420   public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
1421   {
1422     if(viewport.cursorMode)
1423     {
1424       alignPanel.seqPanel.keyboardNo1 = null;
1425       alignPanel.seqPanel.keyboardNo2 = null;
1426     }
1427     viewport.setSelectionGroup(null);
1428     viewport.getColumnSelection().clear();
1429     viewport.setSelectionGroup(null);
1430     alignPanel.seqPanel.seqCanvas.highlightSearchResults(null);
1431     alignPanel.idPanel.idCanvas.searchResults = null;
1432     alignPanel.repaint();
1433     PaintRefresher.Refresh(this, viewport.getSequenceSetId());
1434   }
1435
1436   /**
1437    * DOCUMENT ME!
1438    *
1439    * @param e DOCUMENT ME!
1440    */
1441   public void invertSequenceMenuItem_actionPerformed(ActionEvent e)
1442   {
1443     SequenceGroup sg = viewport.getSelectionGroup();
1444
1445     if (sg == null)
1446     {
1447       selectAllSequenceMenuItem_actionPerformed(null);
1448
1449       return;
1450     }
1451
1452     for (int i = 0; i < viewport.getAlignment().getSequences().size();
1453          i++)
1454     {
1455       sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
1456     }
1457
1458     PaintRefresher.Refresh(this, viewport.getSequenceSetId());
1459   }
1460
1461   public void invertColSel_actionPerformed(ActionEvent e)
1462   {
1463     viewport.invertColumnSelection();
1464     alignPanel.repaint();
1465   }
1466
1467
1468   /**
1469    * DOCUMENT ME!
1470    *
1471    * @param e DOCUMENT ME!
1472    */
1473   public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
1474   {
1475     trimAlignment(true);
1476   }
1477
1478   /**
1479    * DOCUMENT ME!
1480    *
1481    * @param e DOCUMENT ME!
1482    */
1483   public void remove2RightMenuItem_actionPerformed(ActionEvent e)
1484   {
1485       trimAlignment(false);
1486   }
1487
1488   void trimAlignment(boolean trimLeft)
1489   {
1490     ColumnSelection colSel = viewport.getColumnSelection();
1491     int column;
1492
1493     if (colSel.size() > 0)
1494     {
1495       if(trimLeft)
1496         column = colSel.getMin();
1497       else
1498         column = colSel.getMax();
1499
1500       SequenceI [] seqs;
1501       if(viewport.getSelectionGroup()!=null)
1502         seqs = viewport.getSelectionGroup().getSequencesAsArray(true);
1503       else
1504         seqs = viewport.alignment.getSequencesArray();
1505
1506
1507       TrimRegionCommand trimRegion;
1508       if(trimLeft)
1509       {
1510         trimRegion = new TrimRegionCommand("Remove Left",
1511                                     TrimRegionCommand.TRIM_LEFT,
1512                                     seqs,
1513                                     column,
1514                                     viewport.alignment,
1515                                     viewport.colSel,
1516                                     viewport.selectionGroup);
1517       }
1518      else
1519      {
1520        trimRegion = new TrimRegionCommand("Remove Right",
1521                                    TrimRegionCommand.TRIM_RIGHT,
1522                                    seqs,
1523                                    column,
1524                                    viewport.alignment,
1525                                    viewport.colSel,
1526                                    viewport.selectionGroup);
1527      }
1528
1529      statusBar.setText("Removed "+trimRegion.getSize()+" columns.");
1530
1531
1532       addHistoryItem(trimRegion);
1533
1534       Vector groups = viewport.alignment.getGroups();
1535
1536       for (int i = 0; i < groups.size(); i++)
1537       {
1538         SequenceGroup sg = (SequenceGroup) groups.get(i);
1539
1540         if ( (trimLeft && !sg.adjustForRemoveLeft(column))
1541             || (!trimLeft && !sg.adjustForRemoveRight(column)))
1542         {
1543           viewport.alignment.deleteGroup(sg);
1544         }
1545       }
1546
1547       viewport.firePropertyChange("alignment", null,
1548                                   viewport.getAlignment().getSequences());
1549     }
1550   }
1551
1552   /**
1553    * DOCUMENT ME!
1554    *
1555    * @param e DOCUMENT ME!
1556    */
1557   public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
1558   {
1559     int start = 0, end = viewport.alignment.getWidth()-1;
1560
1561     SequenceI[] seqs;
1562     if (viewport.getSelectionGroup() != null)
1563     {
1564       seqs = viewport.getSelectionGroup().getSequencesAsArray(true);
1565       start = viewport.getSelectionGroup().getStartRes();
1566       end = viewport.getSelectionGroup().getEndRes();
1567     }
1568     else
1569       seqs = viewport.alignment.getSequencesArray();
1570
1571
1572     RemoveGapColCommand removeGapCols =
1573         new RemoveGapColCommand("Remove Gapped Columns",
1574                                 seqs,
1575                                 start, end,
1576                                 viewport.getGapCharacter());
1577
1578     addHistoryItem(removeGapCols);
1579
1580     statusBar.setText("Removed "+removeGapCols.getSize()+" empty columns.");
1581
1582     //This is to maintain viewport position on first residue
1583     //of first sequence
1584     SequenceI seq = viewport.alignment.getSequenceAt(0);
1585     int startRes = seq.findPosition(viewport.startRes);
1586    // ShiftList shifts;
1587    // viewport.getAlignment().removeGaps(shifts=new ShiftList());
1588    // edit.alColumnChanges=shifts.getInverse();
1589    // if (viewport.hasHiddenColumns)
1590    //   viewport.getColumnSelection().compensateForEdits(shifts);
1591    viewport.setStartRes(seq.findIndex(startRes)-1);
1592    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
1593
1594   }
1595
1596   /**
1597    * DOCUMENT ME!
1598    *
1599    * @param e DOCUMENT ME!
1600    */
1601   public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
1602   {
1603     int start = 0, end = viewport.alignment.getWidth()-1;
1604
1605     SequenceI[] seqs;
1606     if (viewport.getSelectionGroup() != null)
1607     {
1608       seqs = viewport.getSelectionGroup().getSequencesAsArray(true);
1609       start = viewport.getSelectionGroup().getStartRes();
1610       end = viewport.getSelectionGroup().getEndRes();
1611     }
1612     else
1613       seqs = viewport.alignment.getSequencesArray();
1614
1615     //This is to maintain viewport position on first residue
1616     //of first sequence
1617     SequenceI seq = viewport.alignment.getSequenceAt(0);
1618     int startRes = seq.findPosition(viewport.startRes);
1619
1620     addHistoryItem(new RemoveGapsCommand("Remove Gaps",
1621                                            seqs,
1622                                            start, end,
1623                      viewport.getGapCharacter()));
1624
1625     viewport.setStartRes(seq.findIndex(startRes)-1);
1626
1627     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
1628
1629   }
1630
1631   /**
1632    * DOCUMENT ME!
1633    *
1634    * @param e DOCUMENT ME!
1635    */
1636   public void padGapsMenuitem_actionPerformed(ActionEvent e)
1637   {
1638     viewport.padGaps = padGapsMenuitem.isSelected();
1639
1640     viewport.firePropertyChange("alignment",
1641                                 null,
1642                                 viewport.getAlignment().getSequences());
1643   }
1644
1645   /**
1646    * DOCUMENT ME!
1647    *
1648    * @param e DOCUMENT ME!
1649    */
1650   public void findMenuItem_actionPerformed(ActionEvent e)
1651   {
1652     JInternalFrame frame = new JInternalFrame();
1653     Finder finder = new Finder(viewport, alignPanel, frame);
1654     frame.setContentPane(finder);
1655     frame.setLayer(JLayeredPane.PALETTE_LAYER);
1656     Desktop.addInternalFrame(frame, "Find", 340, 110);
1657   }
1658
1659   /**
1660    * DOCUMENT ME!
1661    *
1662    * @param e DOCUMENT ME!
1663    */
1664   public void font_actionPerformed(ActionEvent e)
1665   {
1666     new FontChooser(alignPanel);
1667   }
1668
1669   public void smoothFont_actionPerformed(ActionEvent e)
1670   {
1671     viewport.antiAlias = smoothFont.isSelected();
1672     alignPanel.annotationPanel.image = null;
1673     alignPanel.repaint();
1674   }
1675
1676
1677   /**
1678    * DOCUMENT ME!
1679    *
1680    * @param e DOCUMENT ME!
1681    */
1682   protected void seqLimit_actionPerformed(ActionEvent e)
1683   {
1684     viewport.setShowJVSuffix(seqLimits.isSelected());
1685
1686     alignPanel.idPanel.idCanvas.setPreferredSize(alignPanel.calculateIdWidth());
1687     alignPanel.repaint();
1688   }
1689
1690
1691   /**
1692    * DOCUMENT ME!
1693    *
1694    * @param e DOCUMENT ME!
1695    */
1696   protected void colourTextMenuItem_actionPerformed(ActionEvent e)
1697   {
1698     viewport.setColourText(colourTextMenuItem.isSelected());
1699     alignPanel.repaint();
1700   }
1701
1702   /**
1703    * DOCUMENT ME!
1704    *
1705    * @param e DOCUMENT ME!
1706    */
1707   public void wrapMenuItem_actionPerformed(ActionEvent e)
1708   {
1709     scaleAbove.setVisible(wrapMenuItem.isSelected());
1710     scaleLeft.setVisible(wrapMenuItem.isSelected());
1711     scaleRight.setVisible(wrapMenuItem.isSelected());
1712     viewport.setWrapAlignment(wrapMenuItem.isSelected());
1713     alignPanel.setWrapAlignment(wrapMenuItem.isSelected());
1714   }
1715
1716   public void showAllSeqs_actionPerformed(ActionEvent e)
1717   {
1718     viewport.showAllHiddenSeqs();
1719   }
1720
1721   public void showAllColumns_actionPerformed(ActionEvent e)
1722   {
1723     viewport.showAllHiddenColumns();
1724     repaint();
1725   }
1726
1727   public void hideSelSequences_actionPerformed(ActionEvent e)
1728   {
1729     viewport.hideAllSelectedSeqs();
1730     alignPanel.repaint();
1731   }
1732
1733   public void hideSelColumns_actionPerformed(ActionEvent e)
1734   {
1735     viewport.hideSelectedColumns();
1736     alignPanel.repaint();
1737   }
1738
1739   public void hiddenMarkers_actionPerformed(ActionEvent e)
1740   {
1741     viewport.setShowHiddenMarkers(hiddenMarkers.isSelected());
1742     repaint();
1743   }
1744
1745   /**
1746    * DOCUMENT ME!
1747    *
1748    * @param e DOCUMENT ME!
1749    */
1750   protected void scaleAbove_actionPerformed(ActionEvent e)
1751   {
1752     viewport.setScaleAboveWrapped(scaleAbove.isSelected());
1753     alignPanel.repaint();
1754   }
1755
1756   /**
1757    * DOCUMENT ME!
1758    *
1759    * @param e DOCUMENT ME!
1760    */
1761   protected void scaleLeft_actionPerformed(ActionEvent e)
1762   {
1763     viewport.setScaleLeftWrapped(scaleLeft.isSelected());
1764     alignPanel.repaint();
1765   }
1766
1767   /**
1768    * DOCUMENT ME!
1769    *
1770    * @param e DOCUMENT ME!
1771    */
1772   protected void scaleRight_actionPerformed(ActionEvent e)
1773   {
1774     viewport.setScaleRightWrapped(scaleRight.isSelected());
1775     alignPanel.repaint();
1776   }
1777
1778   /**
1779    * DOCUMENT ME!
1780    *
1781    * @param e DOCUMENT ME!
1782    */
1783   public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
1784   {
1785     viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
1786     alignPanel.repaint();
1787   }
1788
1789   /**
1790    * DOCUMENT ME!
1791    *
1792    * @param e DOCUMENT ME!
1793    */
1794   public void viewTextMenuItem_actionPerformed(ActionEvent e)
1795   {
1796     viewport.setShowText(viewTextMenuItem.isSelected());
1797     alignPanel.repaint();
1798   }
1799
1800   /**
1801    * DOCUMENT ME!
1802    *
1803    * @param e DOCUMENT ME!
1804    */
1805   protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
1806   {
1807     viewport.setRenderGaps(renderGapsMenuItem.isSelected());
1808     alignPanel.repaint();
1809   }
1810
1811
1812   public FeatureSettings featureSettings;
1813   public void featureSettings_actionPerformed(ActionEvent e)
1814   {
1815     if(featureSettings !=null )
1816     {
1817       featureSettings.close();
1818       featureSettings = null;
1819     }
1820     featureSettings = new FeatureSettings(this);
1821   }
1822
1823   /**
1824    * DOCUMENT ME!
1825    *
1826    * @param evt DOCUMENT ME!
1827    */
1828   public void showSeqFeatures_actionPerformed(ActionEvent evt)
1829   {
1830     viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
1831     alignPanel.repaint();
1832     if (alignPanel.getOverviewPanel() != null)
1833     {
1834       alignPanel.getOverviewPanel().updateOverviewImage();
1835     }
1836   }
1837
1838   /**
1839    * DOCUMENT ME!
1840    *
1841    * @param e DOCUMENT ME!
1842    */
1843   public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
1844   {
1845     viewport.setShowAnnotation(annotationPanelMenuItem.isSelected());
1846     alignPanel.setAnnotationVisible(annotationPanelMenuItem.isSelected());
1847   }
1848
1849   /**
1850    * DOCUMENT ME!
1851    *
1852    * @param e DOCUMENT ME!
1853    */
1854   public void overviewMenuItem_actionPerformed(ActionEvent e)
1855   {
1856     if (alignPanel.overviewPanel != null)
1857     {
1858       return;
1859     }
1860
1861     JInternalFrame frame = new JInternalFrame();
1862     OverviewPanel overview = new OverviewPanel(alignPanel);
1863     frame.setContentPane(overview);
1864     Desktop.addInternalFrame(frame, "Overview " + this.getTitle(),
1865                              frame.getWidth(), frame.getHeight());
1866     frame.pack();
1867     frame.setLayer(JLayeredPane.PALETTE_LAYER);
1868     frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
1869     {
1870       public void internalFrameClosed(
1871           javax.swing.event.InternalFrameEvent evt)
1872       {
1873         alignPanel.setOverviewPanel(null);
1874       }
1875       ;
1876     });
1877
1878     alignPanel.setOverviewPanel(overview);
1879   }
1880
1881   /**
1882    * DOCUMENT ME!
1883    *
1884    * @param e DOCUMENT ME!
1885    */
1886   protected void noColourmenuItem_actionPerformed(ActionEvent e)
1887   {
1888     changeColour(null);
1889   }
1890
1891   /**
1892    * DOCUMENT ME!
1893    *
1894    * @param e DOCUMENT ME!
1895    */
1896   public void clustalColour_actionPerformed(ActionEvent e)
1897   {
1898     changeColour(new ClustalxColourScheme(
1899         viewport.alignment.getSequences(), viewport.alignment.getWidth()));
1900   }
1901
1902   /**
1903    * DOCUMENT ME!
1904    *
1905    * @param e DOCUMENT ME!
1906    */
1907   public void zappoColour_actionPerformed(ActionEvent e)
1908   {
1909     changeColour(new ZappoColourScheme());
1910   }
1911
1912   /**
1913    * DOCUMENT ME!
1914    *
1915    * @param e DOCUMENT ME!
1916    */
1917   public void taylorColour_actionPerformed(ActionEvent e)
1918   {
1919     changeColour(new TaylorColourScheme());
1920   }
1921
1922   /**
1923    * DOCUMENT ME!
1924    *
1925    * @param e DOCUMENT ME!
1926    */
1927   public void hydrophobicityColour_actionPerformed(ActionEvent e)
1928   {
1929     changeColour(new HydrophobicColourScheme());
1930   }
1931
1932   /**
1933    * DOCUMENT ME!
1934    *
1935    * @param e DOCUMENT ME!
1936    */
1937   public void helixColour_actionPerformed(ActionEvent e)
1938   {
1939     changeColour(new HelixColourScheme());
1940   }
1941
1942   /**
1943    * DOCUMENT ME!
1944    *
1945    * @param e DOCUMENT ME!
1946    */
1947   public void strandColour_actionPerformed(ActionEvent e)
1948   {
1949     changeColour(new StrandColourScheme());
1950   }
1951
1952   /**
1953    * DOCUMENT ME!
1954    *
1955    * @param e DOCUMENT ME!
1956    */
1957   public void turnColour_actionPerformed(ActionEvent e)
1958   {
1959     changeColour(new TurnColourScheme());
1960   }
1961
1962   /**
1963    * DOCUMENT ME!
1964    *
1965    * @param e DOCUMENT ME!
1966    */
1967   public void buriedColour_actionPerformed(ActionEvent e)
1968   {
1969     changeColour(new BuriedColourScheme());
1970   }
1971
1972   /**
1973    * DOCUMENT ME!
1974    *
1975    * @param e DOCUMENT ME!
1976    */
1977   public void nucleotideColour_actionPerformed(ActionEvent e)
1978   {
1979     changeColour(new NucleotideColourScheme());
1980   }
1981
1982   public void annotationColour_actionPerformed(ActionEvent e)
1983   {
1984     new AnnotationColourChooser(viewport, alignPanel);
1985   }
1986
1987
1988   /**
1989    * DOCUMENT ME!
1990    *
1991    * @param e DOCUMENT ME!
1992    */
1993   protected void applyToAllGroups_actionPerformed(ActionEvent e)
1994   {
1995     viewport.setColourAppliesToAllGroups(applyToAllGroups.isSelected());
1996   }
1997
1998   /**
1999    * DOCUMENT ME!
2000    *
2001    * @param cs DOCUMENT ME!
2002    */
2003   public void changeColour(ColourSchemeI cs)
2004   {
2005     int threshold = 0;
2006
2007     if(cs!=null)
2008     {
2009       if (viewport.getAbovePIDThreshold())
2010       {
2011         threshold = SliderPanel.setPIDSliderSource(alignPanel, cs,
2012                                                    "Background");
2013
2014         cs.setThreshold(threshold,
2015                         viewport.getIgnoreGapsConsensus());
2016
2017         viewport.setGlobalColourScheme(cs);
2018       }
2019       else
2020       {
2021         cs.setThreshold(0, viewport.getIgnoreGapsConsensus());
2022       }
2023
2024       if (viewport.getConservationSelected())
2025       {
2026
2027         Alignment al = (Alignment) viewport.alignment;
2028         Conservation c = new Conservation("All",
2029                                           ResidueProperties.propHash, 3,
2030                                           al.getSequences(), 0,
2031                                           al.getWidth() - 1);
2032
2033         c.calculate();
2034         c.verdict(false, viewport.ConsPercGaps);
2035
2036         cs.setConservation(c);
2037
2038         cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel, cs,
2039             "Background"));
2040       }
2041       else
2042       {
2043         cs.setConservation(null);
2044       }
2045
2046       cs.setConsensus(viewport.hconsensus);
2047     }
2048
2049     viewport.setGlobalColourScheme(cs);
2050
2051     if (viewport.getColourAppliesToAllGroups())
2052     {
2053       Vector groups = viewport.alignment.getGroups();
2054
2055       for (int i = 0; i < groups.size(); i++)
2056       {
2057         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
2058
2059         if (cs == null)
2060         {
2061           sg.cs = null;
2062           continue;
2063         }
2064
2065         if (cs instanceof ClustalxColourScheme)
2066         {
2067           sg.cs = new ClustalxColourScheme(
2068               sg.getSequences(true), sg.getWidth());
2069         }
2070         else if (cs instanceof UserColourScheme)
2071         {
2072           sg.cs = new UserColourScheme( ( (UserColourScheme) cs).getColours());
2073         }
2074         else
2075         {
2076           try
2077           {
2078             sg.cs = (ColourSchemeI) cs.getClass().newInstance();
2079           }
2080           catch (Exception ex)
2081           {
2082           }
2083         }
2084
2085         if (viewport.getAbovePIDThreshold()
2086             || cs instanceof PIDColourScheme
2087             || cs instanceof Blosum62ColourScheme)
2088         {
2089          sg.cs.setThreshold(threshold,
2090                 viewport.getIgnoreGapsConsensus());
2091
2092          sg.cs.setConsensus(AAFrequency.calculate(
2093              sg.getSequences(true), sg.getStartRes(),
2094              sg.getEndRes()+1));
2095        }
2096         else
2097           sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());
2098
2099
2100         if (viewport.getConservationSelected())
2101         {
2102           Conservation c = new Conservation("Group",
2103                                             ResidueProperties.propHash, 3,
2104                                             sg.getSequences(true),
2105                                             sg.getStartRes(),
2106                                             sg.getEndRes()+1);
2107           c.calculate();
2108           c.verdict(false, viewport.ConsPercGaps);
2109           sg.cs.setConservation(c);
2110         }
2111         else
2112           sg.cs.setConservation(null);
2113       }
2114     }
2115
2116     if (alignPanel.getOverviewPanel() != null)
2117     {
2118       alignPanel.getOverviewPanel().updateOverviewImage();
2119     }
2120
2121     alignPanel.repaint();
2122   }
2123
2124   /**
2125    * DOCUMENT ME!
2126    *
2127    * @param e DOCUMENT ME!
2128    */
2129   protected void modifyPID_actionPerformed(ActionEvent e)
2130   {
2131     if (viewport.getAbovePIDThreshold() && viewport.globalColourScheme!=null)
2132     {
2133       SliderPanel.setPIDSliderSource(alignPanel,
2134                                      viewport.getGlobalColourScheme(),
2135                                      "Background");
2136       SliderPanel.showPIDSlider();
2137     }
2138   }
2139
2140   /**
2141    * DOCUMENT ME!
2142    *
2143    * @param e DOCUMENT ME!
2144    */
2145   protected void modifyConservation_actionPerformed(ActionEvent e)
2146   {
2147     if (viewport.getConservationSelected() && viewport.globalColourScheme!=null)
2148     {
2149       SliderPanel.setConservationSlider(alignPanel,
2150                                         viewport.globalColourScheme,
2151                                         "Background");
2152       SliderPanel.showConservationSlider();
2153     }
2154   }
2155
2156   /**
2157    * DOCUMENT ME!
2158    *
2159    * @param e DOCUMENT ME!
2160    */
2161   protected void conservationMenuItem_actionPerformed(ActionEvent e)
2162   {
2163     viewport.setConservationSelected(conservationMenuItem.isSelected());
2164
2165     viewport.setAbovePIDThreshold(false);
2166     abovePIDThreshold.setSelected(false);
2167
2168     changeColour(viewport.getGlobalColourScheme());
2169
2170     modifyConservation_actionPerformed(null);
2171   }
2172
2173   /**
2174    * DOCUMENT ME!
2175    *
2176    * @param e DOCUMENT ME!
2177    */
2178   public void abovePIDThreshold_actionPerformed(ActionEvent e)
2179   {
2180     viewport.setAbovePIDThreshold(abovePIDThreshold.isSelected());
2181
2182     conservationMenuItem.setSelected(false);
2183     viewport.setConservationSelected(false);
2184
2185     changeColour(viewport.getGlobalColourScheme());
2186
2187     modifyPID_actionPerformed(null);
2188   }
2189
2190   /**
2191    * DOCUMENT ME!
2192    *
2193    * @param e DOCUMENT ME!
2194    */
2195   public void userDefinedColour_actionPerformed(ActionEvent e)
2196   {
2197     if (e.getActionCommand().equals("User Defined..."))
2198     {
2199       new UserDefinedColours(alignPanel, null);
2200     }
2201     else
2202     {
2203       UserColourScheme udc = (UserColourScheme) UserDefinedColours.
2204           getUserColourSchemes().get(e.getActionCommand());
2205
2206       changeColour(udc);
2207     }
2208   }
2209
2210   public void updateUserColourMenu()
2211   {
2212
2213     Component[] menuItems = colourMenu.getMenuComponents();
2214     int i, iSize = menuItems.length;
2215     for (i = 0; i < iSize; i++)
2216     {
2217       if (menuItems[i].getName() != null &&
2218           menuItems[i].getName().equals("USER_DEFINED"))
2219       {
2220         colourMenu.remove(menuItems[i]);
2221         iSize--;
2222       }
2223     }
2224     if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null)
2225     {
2226       java.util.Enumeration userColours = jalview.gui.UserDefinedColours.
2227           getUserColourSchemes().keys();
2228
2229       while (userColours.hasMoreElements())
2230       {
2231         final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem(userColours.
2232             nextElement().toString());
2233         radioItem.setName("USER_DEFINED");
2234         radioItem.addMouseListener(new MouseAdapter()
2235             {
2236               public void mousePressed(MouseEvent evt)
2237               {
2238                 if(evt.isControlDown() || SwingUtilities.isRightMouseButton(evt))
2239                 {
2240                   radioItem.removeActionListener(radioItem.getActionListeners()[0]);
2241
2242                   int option = JOptionPane.showInternalConfirmDialog(jalview.gui.Desktop.desktop,
2243                       "Remove from default list?",
2244                       "Remove user defined colour",
2245                       JOptionPane.YES_NO_OPTION);
2246                   if(option == JOptionPane.YES_OPTION)
2247                   {
2248                     jalview.gui.UserDefinedColours.removeColourFromDefaults(radioItem.getText());
2249                     colourMenu.remove(radioItem);
2250                   }
2251                   else
2252                     radioItem.addActionListener(new ActionListener()
2253                     {
2254                       public void actionPerformed(ActionEvent evt)
2255                       {
2256                         userDefinedColour_actionPerformed(evt);
2257                       }
2258                     });
2259                 }
2260               }
2261             });
2262         radioItem.addActionListener(new ActionListener()
2263         {
2264           public void actionPerformed(ActionEvent evt)
2265           {
2266             userDefinedColour_actionPerformed(evt);
2267           }
2268         });
2269
2270         colourMenu.insert(radioItem, 15);
2271         colours.add(radioItem);
2272       }
2273     }
2274   }
2275
2276   /**
2277    * DOCUMENT ME!
2278    *
2279    * @param e DOCUMENT ME!
2280    */
2281   public void PIDColour_actionPerformed(ActionEvent e)
2282   {
2283     changeColour(new PIDColourScheme());
2284   }
2285
2286   /**
2287    * DOCUMENT ME!
2288    *
2289    * @param e DOCUMENT ME!
2290    */
2291   public void BLOSUM62Colour_actionPerformed(ActionEvent e)
2292   {
2293     changeColour(new Blosum62ColourScheme());
2294   }
2295
2296   /**
2297    * DOCUMENT ME!
2298    *
2299    * @param e DOCUMENT ME!
2300    */
2301   public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
2302   {
2303     SequenceI [] oldOrder = viewport.getAlignment().getSequencesArray();
2304     AlignmentSorter.sortByPID(viewport.getAlignment(),
2305                               viewport.getAlignment().getSequenceAt(0));
2306     addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder, viewport.alignment));
2307     alignPanel.repaint();
2308   }
2309
2310   /**
2311    * DOCUMENT ME!
2312    *
2313    * @param e DOCUMENT ME!
2314    */
2315   public void sortIDMenuItem_actionPerformed(ActionEvent e)
2316   {
2317     SequenceI [] oldOrder = viewport.getAlignment().getSequencesArray();
2318     AlignmentSorter.sortByID(viewport.getAlignment());
2319     addHistoryItem(new OrderCommand("ID Sort", oldOrder, viewport.alignment));
2320     alignPanel.repaint();
2321   }
2322
2323   /**
2324    * DOCUMENT ME!
2325    *
2326    * @param e DOCUMENT ME!
2327    */
2328   public void sortGroupMenuItem_actionPerformed(ActionEvent e)
2329   {
2330     SequenceI [] oldOrder = viewport.getAlignment().getSequencesArray();
2331     AlignmentSorter.sortByGroup(viewport.getAlignment());
2332     addHistoryItem(new OrderCommand("Group Sort", oldOrder, viewport.alignment));
2333
2334     alignPanel.repaint();
2335   }
2336
2337   /**
2338    * DOCUMENT ME!
2339    *
2340    * @param e DOCUMENT ME!
2341    */
2342   public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
2343   {
2344     new RedundancyPanel(alignPanel, this);
2345   }
2346
2347
2348   /**
2349    * DOCUMENT ME!
2350    *
2351    * @param e DOCUMENT ME!
2352    */
2353   public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
2354   {
2355     if ( (viewport.getSelectionGroup() == null) ||
2356         (viewport.getSelectionGroup().getSize(false) < 2))
2357     {
2358       JOptionPane.showInternalMessageDialog(this,
2359                                             "You must select at least 2 sequences.",
2360                                             "Invalid Selection",
2361                                             JOptionPane.WARNING_MESSAGE);
2362     }
2363     else
2364     {
2365       JInternalFrame frame = new JInternalFrame();
2366       frame.setContentPane(new PairwiseAlignPanel(viewport));
2367       Desktop.addInternalFrame(frame, "Pairwise Alignment", 600, 500);
2368     }
2369   }
2370
2371   /**
2372    * DOCUMENT ME!
2373    *
2374    * @param e DOCUMENT ME!
2375    */
2376   public void PCAMenuItem_actionPerformed(ActionEvent e)
2377   {
2378     if ( ( (viewport.getSelectionGroup() != null) &&
2379           (viewport.getSelectionGroup().getSize(false) < 4) &&
2380           (viewport.getSelectionGroup().getSize(false) > 0)) ||
2381         (viewport.getAlignment().getHeight() < 4))
2382     {
2383       JOptionPane.showInternalMessageDialog(this,
2384                                             "Principal component analysis must take\n" +
2385                                             "at least 4 input sequences.",
2386                                             "Sequence selection insufficient",
2387                                             JOptionPane.WARNING_MESSAGE);
2388
2389       return;
2390     }
2391
2392      new PCAPanel(viewport);
2393   }
2394
2395
2396   public void autoCalculate_actionPerformed(ActionEvent e)
2397   {
2398     viewport.autoCalculateConsensus = autoCalculate.isSelected();
2399     if(viewport.autoCalculateConsensus)
2400     {
2401       viewport.firePropertyChange("alignment",
2402                                   null,
2403                                   viewport.getAlignment().getSequences());
2404     }
2405   }
2406
2407
2408   /**
2409    * DOCUMENT ME!
2410    *
2411    * @param e DOCUMENT ME!
2412    */
2413   public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)
2414   {
2415     NewTreePanel("AV", "PID", "Average distance tree using PID");
2416   }
2417
2418   /**
2419    * DOCUMENT ME!
2420    *
2421    * @param e DOCUMENT ME!
2422    */
2423   public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)
2424   {
2425     NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");
2426   }
2427
2428   /**
2429    * DOCUMENT ME!
2430    *
2431    * @param e DOCUMENT ME!
2432    */
2433   protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)
2434   {
2435     NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");
2436   }
2437
2438   /**
2439    * DOCUMENT ME!
2440    *
2441    * @param e DOCUMENT ME!
2442    */
2443   protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)
2444   {
2445     NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62");
2446   }
2447
2448   /**
2449    * DOCUMENT ME!
2450    *
2451    * @param type DOCUMENT ME!
2452    * @param pwType DOCUMENT ME!
2453    * @param title DOCUMENT ME!
2454    */
2455   void NewTreePanel(String type, String pwType, String title)
2456   {
2457     TreePanel tp;
2458
2459     if (viewport.getSelectionGroup() != null) {
2460       if (viewport.getSelectionGroup().getSize(false) < 3) {
2461         JOptionPane.showMessageDialog(Desktop.desktop,
2462                                       "You need to have more than two sequences selected to build a tree!",
2463                                       "Not enough sequences",
2464                                       JOptionPane.WARNING_MESSAGE);
2465         return;
2466       }
2467
2468       int s = 0;
2469       SequenceGroup sg = viewport.getSelectionGroup();
2470
2471       /* Decide if the selection is a column region */
2472       while (s < sg.getSize(false))
2473       {
2474         if ( ( (SequenceI) sg.getSequences(false).elementAt(s++)).getLength() <
2475             sg.getEndRes())
2476         {
2477           JOptionPane.showMessageDialog(Desktop.desktop,
2478                                         "The selected region to create a tree may\nonly contain residues or gaps.\n" +
2479                                         "Try using the Pad function in the edit menu,\n" +
2480                                         "or one of the multiple sequence alignment web services.",
2481                                         "Sequences in selection are not aligned",
2482                                         JOptionPane.WARNING_MESSAGE);
2483
2484           return;
2485         }
2486       }
2487
2488       title = title + " on region";
2489       tp = new TreePanel(alignPanel, type, pwType);
2490     }
2491     else
2492     {
2493       //are the sequences aligned?
2494       if (!viewport.alignment.isAligned())
2495       {
2496         JOptionPane.showMessageDialog(Desktop.desktop,
2497                                       "The sequences must be aligned before creating a tree.\n" +
2498                                       "Try using the Pad function in the edit menu,\n" +
2499                                       "or one of the multiple sequence alignment web services.",
2500                                       "Sequences not aligned",
2501                                       JOptionPane.WARNING_MESSAGE);
2502
2503         return;
2504       }
2505
2506       if(viewport.alignment.getHeight()<2)
2507         return;
2508
2509       tp = new TreePanel(alignPanel, type, pwType);
2510     }
2511
2512     addTreeMenuItem(tp, title);
2513
2514     Desktop.addInternalFrame(tp, title + " from " + this.title, 600, 500);
2515   }
2516
2517   /**
2518    * DOCUMENT ME!
2519    *
2520    * @param title DOCUMENT ME!
2521    * @param order DOCUMENT ME!
2522    */
2523   public void addSortByOrderMenuItem(String title, final AlignmentOrder order)
2524   {
2525     final JMenuItem item = new JMenuItem("by " + title);
2526     sort.add(item);
2527     item.addActionListener(new java.awt.event.ActionListener()
2528     {
2529       public void actionPerformed(ActionEvent e)
2530       {
2531         SequenceI [] oldOrder = viewport.getAlignment().getSequencesArray();
2532
2533         // TODO: JBPNote - have to map order entries to curent SequenceI pointers
2534         AlignmentSorter.sortBy(viewport.getAlignment(), order);
2535
2536         addHistoryItem(new OrderCommand(order.getName(), oldOrder, viewport.alignment));
2537
2538         alignPanel.repaint();
2539       }
2540     });
2541   }
2542
2543   /**
2544    * Maintain the Order by->Displayed Tree menu.
2545    * Creates a new menu item for a TreePanel with an appropriate
2546    * <code>jalview.analysis.AlignmentSorter</code> call. Listeners are added
2547    * to remove the menu item when the treePanel is closed, and adjust
2548    * the tree leaf to sequence mapping when the alignment is modified.
2549    * @param treePanel Displayed tree window.
2550    * @param title SortBy menu item title.
2551    */
2552   void addTreeMenuItem(final TreePanel treePanel, String title)
2553   {
2554     final JMenuItem item = new JMenuItem(title);
2555
2556     treeCount++;
2557
2558     if (treeCount == 1)
2559     {
2560       sort.add(sortByTreeMenu);
2561     }
2562
2563     sortByTreeMenu.add(item);
2564     item.addActionListener(new java.awt.event.ActionListener()
2565     {
2566       public void actionPerformed(ActionEvent e)
2567       {
2568         SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
2569         AlignmentSorter.sortByTree(viewport.getAlignment(),
2570                                    treePanel.getTree());
2571
2572         addHistoryItem(new OrderCommand("Tree Sort",
2573                                         oldOrder,
2574                                         viewport.alignment));
2575
2576
2577         alignPanel.repaint();
2578       }
2579     });
2580
2581     treePanel.addInternalFrameListener(new javax.swing.event.
2582                                        InternalFrameAdapter()
2583     {
2584       public void internalFrameClosed(
2585           javax.swing.event.InternalFrameEvent evt)
2586       {
2587         treeCount--;
2588         sortByTreeMenu.remove(item);
2589
2590         if (treeCount == 0)
2591         {
2592           sort.remove(sortByTreeMenu);
2593         }
2594       }
2595       ;
2596     });
2597   }
2598
2599   /**
2600    * Work out whether the whole set of sequences
2601    * or just the selected set will be submitted for multiple alignment.
2602    *
2603    */
2604   private jalview.datamodel.AlignmentView gatherSequencesForAlignment()
2605   {
2606     // Now, check we have enough sequences
2607     AlignmentView msa = null;
2608
2609     if ( (viewport.getSelectionGroup() != null) &&
2610         (viewport.getSelectionGroup().getSize(false) > 1))
2611     {
2612       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!
2613       /*SequenceGroup seqs = viewport.getSelectionGroup();
2614       int sz;
2615       msa = new SequenceI[sz = seqs.getSize(false)];
2616
2617       for (int i = 0; i < sz; i++)
2618       {
2619         msa[i] = (SequenceI) seqs.getSequenceAt(i);
2620       } */
2621       msa = viewport.getAlignmentView(true);
2622     }
2623     else
2624     {
2625       /*Vector seqs = viewport.getAlignment().getSequences();
2626
2627       if (seqs.size() > 1)
2628       {
2629         msa = new SequenceI[seqs.size()];
2630
2631         for (int i = 0; i < seqs.size(); i++)
2632         {
2633           msa[i] = (SequenceI) seqs.elementAt(i);
2634         }
2635       }*/
2636       msa = viewport.getAlignmentView(false);
2637     }
2638     return msa;
2639   }
2640
2641   /**
2642    * Decides what is submitted to a secondary structure prediction service,
2643    * the currently selected sequence, or the currently selected alignment
2644    * (where the first sequence in the set is the one that the prediction
2645    * will be for).
2646    */
2647   AlignmentView gatherSeqOrMsaForSecStrPrediction()
2648   {
2649    AlignmentView seqs = null;
2650
2651     if ( (viewport.getSelectionGroup() != null) &&
2652         (viewport.getSelectionGroup().getSize(false) > 0))
2653     {
2654       seqs = viewport.getAlignmentView(true);
2655     }
2656     else
2657     {
2658       seqs = viewport.getAlignmentView(false);
2659     }
2660     // limit sequences - JBPNote in future - could spawn multiple prediction jobs
2661     // TODO: viewport.alignment.isAligned is a global state - the local selection may well be aligned - we preserve 2.0.8 behaviour for moment.
2662     if (!viewport.alignment.isAligned())
2663     {
2664       seqs.setSequences(new SeqCigar[] { seqs.getSequences()[0] } );
2665     }
2666     return seqs;
2667   }
2668   /**
2669    * DOCUMENT ME!
2670    *
2671    * @param e DOCUMENT ME!
2672    */
2673   protected void LoadtreeMenuItem_actionPerformed(ActionEvent e)
2674   {
2675     // Pick the tree file
2676     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2677         getProperty(
2678             "LAST_DIRECTORY"));
2679     chooser.setFileView(new JalviewFileView());
2680     chooser.setDialogTitle("Select a newick-like tree file");
2681     chooser.setToolTipText("Load a tree file");
2682
2683     int value = chooser.showOpenDialog(null);
2684
2685     if (value == JalviewFileChooser.APPROVE_OPTION)
2686     {
2687       String choice = chooser.getSelectedFile().getPath();
2688       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
2689
2690       try
2691       {
2692         jalview.io.NewickFile fin = new jalview.io.NewickFile(choice,
2693             "File");
2694         viewport.setCurrentTree(ShowNewickTree(fin, choice).getTree());
2695       }
2696       catch (Exception ex)
2697       {
2698         JOptionPane.showMessageDialog(Desktop.desktop,
2699                                       "Problem reading tree file",
2700                                       ex.getMessage(),
2701                                       JOptionPane.WARNING_MESSAGE);
2702         ex.printStackTrace();
2703       }
2704     }
2705   }
2706
2707
2708   public TreePanel ShowNewickTree(NewickFile nf, String title)
2709   {
2710     return ShowNewickTree(nf,title,600,500,4,5);
2711   }
2712   public TreePanel ShowNewickTree(NewickFile nf, String title, AlignmentView input)
2713   {
2714     return ShowNewickTree(nf,title, input, 600,500,4,5);
2715   }
2716   public TreePanel ShowNewickTree(NewickFile nf, String title, int w,int h,int x, int y) {
2717     return ShowNewickTree(nf, title, null, w, h, x, y);
2718   }
2719   /**
2720    * Add a treeviewer for the tree extracted from a newick file object to the current alignment view
2721    *
2722    * @param nf the tree
2723    * @param title tree viewer title
2724    * @param input Associated alignment input data (or null)
2725    * @param w width
2726    * @param h height
2727    * @param x position
2728    * @param y position
2729    * @return TreePanel handle
2730    */
2731   public TreePanel ShowNewickTree(NewickFile nf, String title, AlignmentView input, int w,int h,int x, int y) {
2732     TreePanel tp = null;
2733
2734     try
2735     {
2736       nf.parse();
2737
2738       if (nf.getTree() != null)
2739       {
2740         tp = new TreePanel(alignPanel,
2741                            "FromFile",
2742                            title,
2743                            nf, input);
2744
2745         tp.setSize(w,h);
2746
2747         if(x>0 && y>0)
2748           tp.setLocation(x,y);
2749
2750
2751         Desktop.addInternalFrame(tp, title, w, h);
2752         addTreeMenuItem(tp, title);
2753       }
2754     }
2755     catch (Exception ex)
2756     {
2757       ex.printStackTrace();
2758     }
2759
2760     return tp;
2761   }
2762
2763   class PrintThread
2764       extends Thread
2765   {
2766     public void run()
2767     {
2768       PrinterJob printJob = PrinterJob.getPrinterJob();
2769       PageFormat pf = printJob.pageDialog(printJob.defaultPage());
2770       printJob.setPrintable(alignPanel, pf);
2771
2772       if (printJob.printDialog())
2773       {
2774         try
2775         {
2776           printJob.print();
2777         }
2778         catch (Exception PrintException)
2779         {
2780           PrintException.printStackTrace();
2781         }
2782       }
2783     }
2784   }
2785
2786   /**
2787    * Generates menu items and listener event actions for web service clients
2788    *
2789    */
2790   public void BuildWebServiceMenu()
2791   {
2792     if ( (Discoverer.services != null)
2793         && (Discoverer.services.size() > 0))
2794     {
2795       Vector msaws = (Vector) Discoverer.services.get("MsaWS");
2796       Vector secstrpr = (Vector) Discoverer.services.get("SecStrPred");
2797       Vector wsmenu = new Vector();
2798       final AlignFrame af = this;
2799       if (msaws != null)
2800       {
2801         // Add any Multiple Sequence Alignment Services
2802         final JMenu msawsmenu = new JMenu("Alignment");
2803         for (int i = 0, j = msaws.size(); i < j; i++)
2804         {
2805           final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle) msaws.
2806               get(i);
2807           final JMenuItem method = new JMenuItem(sh.getName());
2808           method.addActionListener(new ActionListener()
2809           {
2810             public void actionPerformed(ActionEvent e)
2811             {
2812               AlignmentView msa = gatherSequencesForAlignment();
2813               new jalview.ws.MsaWSClient(sh, title, msa,
2814                   false, true, viewport.getAlignment().getDataset(), af);
2815
2816             }
2817
2818           });
2819           msawsmenu.add(method);
2820           // Deal with services that we know accept partial alignments.
2821           if (sh.getName().indexOf("lustal") > -1)
2822           {
2823             // We know that ClustalWS can accept partial alignments for refinement.
2824             final JMenuItem methodR = new JMenuItem(sh.getName()+" Realign");
2825             methodR.addActionListener(new ActionListener()
2826             {
2827               public void actionPerformed(ActionEvent e)
2828               {
2829                 AlignmentView msa = gatherSequencesForAlignment();
2830                 new jalview.ws.MsaWSClient(sh, title, msa,
2831                     true, true, viewport.getAlignment().getDataset(), af);
2832
2833               }
2834
2835             });
2836             msawsmenu.add(methodR);
2837
2838           }
2839         }
2840         wsmenu.add(msawsmenu);
2841       }
2842       if (secstrpr != null)
2843       {
2844         // Add any secondary structure prediction services
2845         final JMenu secstrmenu = new JMenu("Secondary Structure Prediction");
2846         for (int i = 0, j = secstrpr.size(); i < j; i++)
2847         {
2848           final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle)
2849               secstrpr.get(i);
2850           final JMenuItem method = new JMenuItem(sh.getName());
2851           method.addActionListener(new ActionListener()
2852           {
2853             public void actionPerformed(ActionEvent e)
2854             {
2855               AlignmentView msa = gatherSeqOrMsaForSecStrPrediction();
2856               if (msa.getSequences().length == 1)
2857               {
2858                 // Single Sequence prediction
2859                 new jalview.ws.JPredClient(sh, title, false, msa, af, true);
2860               }
2861               else
2862               {
2863                 if (msa.getSequences().length > 1)
2864                 {
2865                   // Sequence profile based prediction
2866                   new jalview.ws.JPredClient(sh,
2867                       title, true, msa, af, true);
2868                 }
2869               }
2870             }
2871           });
2872           secstrmenu.add(method);
2873         }
2874         wsmenu.add(secstrmenu);
2875       }
2876       this.webService.removeAll();
2877       for (int i = 0, j = wsmenu.size(); i < j; i++)
2878       {
2879         webService.add( (JMenu) wsmenu.get(i));
2880       }
2881     }
2882     else
2883     {
2884       this.webService.removeAll();
2885       this.webService.add(this.webServiceNoServices);
2886     }
2887     // TODO: add in rediscovery function
2888     // TODO: reduce code redundancy.
2889     // TODO: group services by location as well as function.
2890   }
2891
2892  /* public void vamsasStore_actionPerformed(ActionEvent e)
2893   {
2894     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2895         getProperty("LAST_DIRECTORY"));
2896
2897     chooser.setFileView(new JalviewFileView());
2898     chooser.setDialogTitle("Export to Vamsas file");
2899     chooser.setToolTipText("Export");
2900
2901     int value = chooser.showSaveDialog(this);
2902
2903     if (value == JalviewFileChooser.APPROVE_OPTION)
2904     {
2905       jalview.io.VamsasDatastore vs = new jalview.io.VamsasDatastore(viewport);
2906       //vs.store(chooser.getSelectedFile().getAbsolutePath()   );
2907       vs.storeJalview( chooser.getSelectedFile().getAbsolutePath(), this);
2908     }
2909   }*/
2910
2911
2912
2913
2914 public void showTranslation_actionPerformed(ActionEvent e)
2915 {
2916   SequenceI [] selection = viewport.getSelectionAsNewSequence();
2917   String [] seqstring = viewport.getViewAsString(true);
2918
2919   int s, sSize = selection.length;
2920   SequenceI [] newSeq = new SequenceI[sSize];
2921
2922   int res, resSize;
2923   StringBuffer protein;
2924   String seq;
2925   for(s=0; s<sSize; s++)
2926   {
2927     protein = new StringBuffer();
2928     seq = AlignSeq.extractGaps("-. ", seqstring[s]);
2929     resSize = seq.length();
2930     resSize -= resSize%3;
2931
2932     for(res = 0; res < resSize; res+=3)
2933     {
2934       String codon = seq.substring(res, res+3);
2935       codon = codon.replace('U', 'T');
2936       String aa = ResidueProperties.codonTranslate(codon);
2937       if(aa==null)
2938         protein.append(viewport.getGapCharacter());
2939       else if(aa.equals("STOP"))
2940         protein.append("X");
2941       else
2942         protein.append( aa );
2943     }
2944     newSeq[s] = new Sequence(selection[s].getName(),
2945                              protein.toString());
2946   }
2947
2948
2949   AlignmentI al = new Alignment(newSeq);
2950   al.setDataset(null);
2951
2952
2953   ////////////////////////////////
2954   // Copy annotations across
2955   jalview.datamodel.AlignmentAnnotation[] annotations
2956       = viewport.alignment.getAlignmentAnnotation();
2957   int a, aSize;
2958   if(annotations!=null)
2959   {
2960     for (int i = 0; i < annotations.length; i++)
2961     {
2962       if (annotations[i].label.equals("Quality") ||
2963           annotations[i].label.equals("Conservation") ||
2964           annotations[i].label.equals("Consensus"))
2965       {
2966         continue;
2967       }
2968
2969       aSize = viewport.alignment.getWidth() / 3;
2970       jalview.datamodel.Annotation[] anots =
2971           new jalview.datamodel.Annotation[aSize];
2972
2973       for (a = 0; a < viewport.alignment.getWidth(); a++)
2974       {
2975         if (annotations[i].annotations[a] == null
2976             || annotations[i].annotations[a] == null)
2977           continue;
2978
2979         anots[a / 3] = new Annotation(
2980             annotations[i].annotations[a].displayCharacter,
2981             annotations[i].annotations[a].description,
2982             annotations[i].annotations[a].secondaryStructure,
2983             annotations[i].annotations[a].value,
2984             annotations[i].annotations[a].colour);
2985       }
2986
2987       jalview.datamodel.AlignmentAnnotation aa
2988           = new jalview.datamodel.AlignmentAnnotation(annotations[i].label,
2989           annotations[i].description, anots);
2990       al.addAnnotation(aa);
2991     }
2992   }
2993
2994     AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
2995     Desktop.addInternalFrame(af, "Translation of "+this.getTitle(),
2996                              DEFAULT_WIDTH,
2997                              DEFAULT_HEIGHT);
2998
2999
3000
3001
3002 }
3003
3004 /**
3005  * DOCUMENT ME!
3006  *
3007  * @param String DOCUMENT ME!
3008  */
3009 public boolean parseFeaturesFile(String file, String type)
3010 {
3011     boolean featuresFile = false;
3012     try{
3013       featuresFile = new FeaturesFile(file, type).parse(viewport.alignment.getDataset(),
3014                                          alignPanel.seqPanel.seqCanvas.
3015                                          getFeatureRenderer().featureColours,
3016                                          false);
3017     }
3018     catch(Exception ex)
3019     {
3020       ex.printStackTrace();
3021     }
3022
3023     if(featuresFile)
3024     {
3025       viewport.showSequenceFeatures = true;
3026       showSeqFeatures.setSelected(true);
3027       alignPanel.repaint();
3028     }
3029
3030     return featuresFile;
3031 }
3032
3033 public void dragEnter(DropTargetDragEvent evt)
3034 {}
3035
3036 public void dragExit(DropTargetEvent evt)
3037 {}
3038
3039 public void dragOver(DropTargetDragEvent evt)
3040 {}
3041
3042 public void dropActionChanged(DropTargetDragEvent evt)
3043 {}
3044
3045 public void drop(DropTargetDropEvent evt)
3046 {
3047     Transferable t = evt.getTransferable();
3048     java.util.List files = null;
3049
3050     try
3051     {
3052       DataFlavor uriListFlavor = new DataFlavor("text/uri-list;class=java.lang.String");
3053       if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3054       {
3055         //Works on Windows and MacOSX
3056         evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3057         files = (java.util.List) t.getTransferData(DataFlavor.javaFileListFlavor);
3058       }
3059       else if (t.isDataFlavorSupported(uriListFlavor))
3060       {
3061         // This is used by Unix drag system
3062         evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3063         String data = (String) t.getTransferData(uriListFlavor);
3064         files = new java.util.ArrayList(1);
3065         for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3066             data,
3067             "\r\n");
3068              st.hasMoreTokens(); )
3069         {
3070           String s = st.nextToken();
3071           if (s.startsWith("#"))
3072           {
3073             // the line is a comment (as per the RFC 2483)
3074             continue;
3075           }
3076
3077           java.net.URI uri = new java.net.URI(s);
3078           java.io.File file = new java.io.File(uri);
3079           files.add(file);
3080         }
3081       }
3082     }
3083     catch (Exception e)
3084     {
3085       e.printStackTrace();
3086     }
3087     if (files != null)
3088     {
3089       try
3090       {
3091
3092         for (int i = 0; i < files.size(); i++)
3093         {
3094           loadJalviewDataFile(files.get(i).toString());
3095         }
3096       }
3097       catch (Exception ex)
3098       {
3099         ex.printStackTrace();
3100       }
3101     }
3102 }
3103
3104   // This method will attempt to load a "dropped" file first by testing
3105   // whether its and Annotation file, then features file. If both are
3106   // false then the user may have dropped an alignment file onto this
3107   // AlignFrame
3108    public void loadJalviewDataFile(String file)
3109   {
3110     try{
3111       String protocol = "File";
3112
3113       if (file.indexOf("http:") > -1 || file.indexOf("file:") > -1)
3114       {
3115         protocol = "URL";
3116       }
3117
3118       boolean isAnnotation = new AnnotationFile().readAnnotationFile(viewport.
3119           alignment, file);
3120
3121       if (!isAnnotation)
3122       {
3123         boolean isGroupsFile = parseFeaturesFile(file,protocol);
3124         if (!isGroupsFile)
3125         {
3126           String format = new IdentifyFile().Identify(file, protocol);
3127
3128           if(format.equalsIgnoreCase("JnetFile"))
3129           {
3130             jalview.io.JPredFile predictions = new jalview.io.JPredFile(
3131                 file, protocol);
3132             new JnetAnnotationMaker().add_annotation(predictions,
3133                 viewport.getAlignment(),
3134                 0, false);
3135             alignPanel.adjustAnnotationHeight();
3136             alignPanel.repaint();
3137           }
3138           else
3139             new FileLoader().LoadFile(viewport, file, protocol, format);
3140         }
3141       }
3142       else
3143       {
3144         // (isAnnotation)
3145         alignPanel.adjustAnnotationHeight();
3146       }
3147
3148     }catch(Exception ex)
3149     {
3150       ex.printStackTrace();
3151     }
3152   }
3153
3154   public void tabSelectionChanged(int index)
3155   {
3156     if (index > -1)
3157     {
3158       alignPanel = (AlignmentPanel) alignPanels.elementAt(index);
3159       viewport = alignPanel.av;
3160       setMenusFromViewport(viewport);
3161     }
3162   }
3163
3164   public void tabbedPane_mousePressed(MouseEvent e)
3165   {
3166     if(SwingUtilities.isRightMouseButton(e))
3167     {
3168       String reply = JOptionPane.showInternalInputDialog(this,
3169           "Enter View Name",
3170           "Edit View Name",
3171           JOptionPane.QUESTION_MESSAGE);
3172
3173       if (reply != null)
3174       {
3175         viewport.viewName = reply;
3176         tabbedPane.setTitleAt( tabbedPane.getSelectedIndex() ,reply);
3177       }
3178     }
3179   }
3180
3181
3182   public AlignViewport getCurrentView()
3183   {
3184     return viewport;
3185   }
3186 }