1 /* QualifierEditor.java 2 * 3 * created: Tue Oct 23 2001 4 * 5 * This file is part of Artemis 6 * 7 * Copyright (C) 2000,2001,2002 Genome Research Limited 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License 11 * as published by the Free Software Foundation; either version 2 12 * of the License, or (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 * 23 * $Header: //tmp/pathsoft/artemis/uk/ac/sanger/artemis/components/QualifierEditor.java,v 1.5 2007-07-09 13:07:38 tjc Exp $ 24 */ 25 26 package uk.ac.sanger.artemis.components; 27 28 import uk.ac.sanger.artemis.*; 29 30 import uk.ac.sanger.artemis.util.ReadOnlyException; 31 import uk.ac.sanger.artemis.io.GFFDocumentEntry; 32 import uk.ac.sanger.artemis.io.Qualifier; 33 import uk.ac.sanger.artemis.io.QualifierInfo; 34 import uk.ac.sanger.artemis.io.QualifierVector; 35 import uk.ac.sanger.artemis.io.QualifierParseException; 36 import uk.ac.sanger.artemis.io.EntryInformation; 37 import uk.ac.sanger.artemis.io.EntryInformationException; 38 39 import java.awt.*; 40 import java.awt.event.*; 41 import java.util.Vector; 42 43 import javax.swing.*; 44 45 /** 46 * This component allows qualifiers to be added to or replaced in several 47 * features at once. 48 * 49 * @author Kim Rutherford <kmr@sanger.ac.uk> 50 * @version $Id: QualifierEditor.java,v 1.5 2007-07-09 13:07:38 tjc Exp $ 51 **/ 52 53 public class QualifierEditor extends JFrame { 54 /** 55 * Create a new QualifierEditor for the given features. 56 **/ QualifierEditor(final FeatureVector features, final EntryGroup entry_group)57 public QualifierEditor (final FeatureVector features, 58 final EntryGroup entry_group) { 59 super (getFrameTitle (features)); 60 61 this.features = features; 62 this.entry_group = entry_group; 63 64 final Font font = Options.getOptions ().getFont (); 65 66 final Feature first_feature = features.elementAt (0); 67 68 final EntryInformation entry_information = 69 first_feature.getEntry ().getEntryInformation (); 70 71 setFont (font); 72 73 boolean isGFF = false; 74 if(entry_group.getDefaultEntry().getEMBLEntry() instanceof GFFDocumentEntry) 75 isGFF = true; 76 final QualifierChoice qualifier_choice = 77 new QualifierChoice (entry_information, first_feature.getKey (), null, isGFF); 78 79 final JPanel outer_qualifier_choice_panel = new JPanel (); 80 final JPanel qualifier_choice_panel = new JPanel (); 81 outer_qualifier_choice_panel.setLayout (new BorderLayout ()); 82 83 outer_qualifier_choice_panel.add (qualifier_choice_panel, "West"); 84 85 final JButton qualifier_button = new JButton ("Insert qualifier:"); 86 87 qualifier_button.addActionListener (new ActionListener () { 88 public void actionPerformed (ActionEvent e) { 89 final String qualifier_name = 90 (String) qualifier_choice.getSelectedItem (); 91 final QualifierInfo qualifier_info = 92 entry_information.getQualifierInfo (qualifier_name); 93 94 if (qualifier_info == null) { 95 new MessageDialog (QualifierEditor.this, "internal error: no " + 96 "qualifier info for " + qualifier_name); 97 } else { 98 qualifier_text_area.append ("/" + qualifier_name); 99 100 switch (qualifier_info.getType ()) { 101 case QualifierInfo.QUOTED_TEXT: 102 qualifier_text_area.append ("=\"\""); 103 break; 104 105 case QualifierInfo.NO_VALUE: 106 case QualifierInfo.OPTIONAL_QUOTED_TEXT: 107 break; 108 109 default: 110 qualifier_text_area.append ("="); 111 } 112 113 qualifier_text_area.append ("\n"); 114 } 115 } 116 117 }); 118 119 qualifier_choice_panel.add (qualifier_button); 120 121 qualifier_choice_panel.add (qualifier_choice); 122 123 getContentPane ().add (outer_qualifier_choice_panel, "North"); 124 125 qualifier_text_area = new QualifierTextArea (); 126 127 add_button.setFont (getFont ()); 128 replace_button.setFont (getFont ()); 129 close_button.setFont (getFont ()); 130 131 add_button.addActionListener (new ActionListener () { 132 public void actionPerformed (ActionEvent e) { 133 addOrReplace (false); 134 } 135 }); 136 137 replace_button.addActionListener (new ActionListener () { 138 public void actionPerformed (ActionEvent e) { 139 addOrReplace (true); 140 } 141 }); 142 143 close_button.addActionListener (new ActionListener () { 144 public void actionPerformed (ActionEvent e) { 145 dispose (); 146 } 147 }); 148 149 button_panel.setFont (getFont ()); 150 151 button_panel.add (replace_button); 152 button_panel.add (add_button); 153 button_panel.add (close_button); 154 155 getContentPane ().add (qualifier_text_area, "Center"); 156 getContentPane ().add (button_panel, "South"); 157 158 addWindowListener (new WindowAdapter () { 159 public void windowClosing (WindowEvent event) { 160 dispose (); 161 } 162 }); 163 164 pack (); 165 166 final Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); 167 setLocation (new Point ((screen.width - getSize ().width) / 2, 168 (screen.height - getSize ().height) / 2)); 169 } 170 171 /** 172 * Add to or replace the qualifiers in all the features that were passed to 173 * the constructor with the qualifiers from qualifier_text_area. 174 * @param replace If false any existing qualifiers of the same name in the 175 * features are left unchanged. If true existing qualifiers of the same 176 * name in the features will be deleted. 177 **/ addOrReplace(final boolean replace)178 private void addOrReplace (final boolean replace) { 179 try 180 { 181 entry_group.getActionController().startAction(); 182 183 // this will contain one QualifierVector object for each Feature in the 184 // features vector (in the same order) 185 final Vector qualifier_vector_vector = new Vector(); 186 final int features_size = features.size(); 187 188 for(int i = 0; i<features_size; ++i) 189 { 190 final Feature this_feature = features.elementAt(i); 191 192 final Entry this_feature_entry = this_feature.getEntry(); 193 194 if(this_feature_entry == null) 195 { 196 // feature has already been deleted 197 qualifier_vector_vector.addElement(null); 198 } 199 else 200 { 201 final EntryInformation entry_information = 202 this_feature_entry.getEntryInformation(); 203 204 try 205 { 206 final QualifierVector qualifiers = 207 qualifier_text_area.getParsedQualifiers(entry_information); 208 209 qualifier_vector_vector.addElement(qualifiers); 210 211 } 212 catch(QualifierParseException e) 213 { 214 new MessageDialog(this, 215 "error while parsing: " + e.getMessage()); 216 return; 217 } 218 } 219 } 220 221 if(qualifier_vector_vector.size() != features_size) 222 throw new Error("Internal error in QualifierEditor.add() - " + 223 "mismatched array sizes"); 224 225 for(int feature_index = 0; feature_index < features_size; 226 ++feature_index) 227 { 228 final Feature this_feature = features.elementAt(feature_index); 229 this_feature.resetColour(); 230 231 if(qualifier_vector_vector.elementAt(feature_index) == null) 232 continue; 233 234 final QualifierVector qualifier_vector = 235 (QualifierVector)qualifier_vector_vector.elementAt(feature_index); 236 237 final int qualifier_vector_size = qualifier_vector.size(); 238 239 for(int qualifier_index = 0; qualifier_index < qualifier_vector_size; 240 ++qualifier_index) 241 { 242 final Qualifier this_qualifier = 243 (Qualifier)qualifier_vector.elementAt(qualifier_index); 244 245 if(replace) 246 { 247 try 248 { 249 this_feature.setQualifier(this_qualifier); 250 } 251 catch(EntryInformationException e) 252 { 253 new MessageDialog(this, 254 "failed to add qualifiers to: " + 255 this_feature.getIDString() + ": " + 256 e.getMessage()); 257 } 258 catch(ReadOnlyException e) 259 { 260 new MessageDialog(this, 261 "failed to add qualifiers to read-only " + 262 "feature: " + this_feature.getIDString() + 263 ": " + e.getMessage()); 264 } 265 } 266 else 267 { 268 try 269 { 270 this_feature.addQualifierValues(this_qualifier); 271 } 272 catch(EntryInformationException e) 273 { 274 new MessageDialog(this, 275 "failed to add qualifiers to: " + 276 this_feature.getIDString() + ": " + 277 e.getMessage()); 278 } 279 catch(ReadOnlyException e) 280 { 281 new MessageDialog(this, 282 "failed to add qualifiers to read-only " + 283 "feature: " + this_feature.getIDString() + 284 ": " + e.getMessage()); 285 } 286 287 } 288 } 289 } 290 } 291 finally 292 { 293 entry_group.getActionController().endAction(); 294 } 295 } 296 297 /** 298 * Return an appropriate String to use for the title of this JFrame. 299 **/ getFrameTitle(final FeatureVector features)300 static private String getFrameTitle (final FeatureVector features) { 301 boolean etc_flag = false; 302 303 final StringBuffer buffer = new StringBuffer (); 304 305 final int MAX_LENGTH = 80; 306 307 for (int i = 0 ; i < features.size () ; ++i) { 308 final Feature this_feature = features.elementAt (i); 309 310 final String feature_name = this_feature.getIDString (); 311 312 if (feature_name == null) { 313 etc_flag = true; 314 continue; 315 } 316 317 if (buffer.length () + feature_name.length () < MAX_LENGTH) { 318 if (buffer.length () == 0) { 319 buffer.append ("Add or replace qualifiers of: "); 320 buffer.append (feature_name); 321 } else { 322 buffer.append (", ").append (feature_name); 323 } 324 } else { 325 etc_flag = true; 326 break; 327 } 328 } 329 330 if (buffer.length () == 0) { 331 buffer.append ("Add or replace qualifiers"); 332 } else { 333 if (etc_flag) { 334 buffer.append (", ..."); 335 } 336 } 337 338 return buffer.toString (); 339 } 340 341 private QualifierTextArea qualifier_text_area; 342 343 private JButton add_button = new JButton ("Add"); 344 private JButton replace_button = new JButton ("Replace"); 345 private JButton close_button = new JButton ("Close"); 346 347 private FlowLayout flow_layout = 348 new FlowLayout (FlowLayout.CENTER, 25, 5); 349 350 private JPanel button_panel = new JPanel (flow_layout); 351 352 /** 353 * The Feature objects that were passed to the constructor. 354 **/ 355 private FeatureVector features = new FeatureVector (); 356 357 /** 358 * The EntryGroup that contains the Features (passed to the constructor). 359 **/ 360 private EntryGroup entry_group; 361 } 362