source: trunk/gli/src/org/greenstone/gatherer/gems/GEMS.java@ 9640

Last change on this file since 9640 was 9373, checked in by mdewsnip, 19 years ago

Removed unused variable.

  • Property svn:keywords set to Author Date Id Revision
File size: 94.0 KB
Line 
1 /**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at th * University of Waikato, New Zealand.
6 *
7 * <BR><BR>
8 *
9 * Author: John Thompson, Greenstone Digital Library, University of Waikato
10 *
11 * <BR><BR>
12 *
13 * Copyright (C) 1999 New Zealand Digital Library Project
14 *
15 * <BR><BR>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * <BR><BR>
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * <BR><BR>
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34 *############################################## ##########################
35 */
36package org.greenstone.gatherer.gems;
37
38import java.awt.*;
39import java.awt.event.*;
40import java.io.File;
41import java.io.PrintStream;
42import java.io.FileInputStream;
43import java.io.BufferedReader;
44import java.io.FileOutputStream;
45import java.io.OutputStreamWriter;
46import java.io.DataInputStream;
47import java.io.IOException;
48import java.io.InputStreamReader;
49import java.io.PrintWriter;
50import java.util.*;
51import javax.swing.*;
52import java.lang.String;
53import javax.swing.event.*;
54import javax.swing.filechooser.*;
55import javax.swing.text.*;
56import javax.swing.tree.*;
57import org.greenstone.gatherer.Configuration;
58import org.greenstone.gatherer.DebugStream;
59import org.greenstone.gatherer.Dictionary;
60import org.greenstone.gatherer.GetOpt;
61import org.greenstone.gatherer.gui.GComboBox;
62import org.greenstone.gatherer.gui.GLIButton;
63import org.greenstone.gatherer.gui.HelpFrame;
64import org.greenstone.gatherer.gui.ModalDialog;
65import org.greenstone.gatherer.gui.NonWhitespaceField;
66import org.greenstone.gatherer.util.Codec;
67import org.greenstone.gatherer.util.Utility;
68import org.w3c.dom.*;
69
70
71
72/** Provides a GUI and relevant suite of tools for the editing of the metadata set associated with this collection. Again I have tried to capture a file manager type feel, with a tree showing the various set-element relations to the left of the dialog, and the right side showing details on the current tree selection. When a set is selected these details include a list of attributes, while when an element is selected this list is joined by another showing assigned values. In order for the editor to be stable and consistant with the rest of the tool, care must be taken for fire appropriate events whenever the sets are changed. There is also the addded complexity of determining what actions have to occur in order for a users edit of an assigned value to be completed, i.e. if the user chooses to remove a value then a call must be made to record_set.root.removeMetadata() to ensure all such values are actually removed, so it is not enough just to remove the value from the value model.
73 * @author John Thompson, Greenstone Digital Library, University of Waikato
74 * @version 2.3b
75 */
76public class GEMS
77 extends JFrame
78{
79 static final public int ADD_SET = 0;
80 static final public int NORMAL = 1;
81 static final public int REMOVE_SET = 2;
82
83 /** The default size of the editor dialog. */
84 static final private Dimension ADD_ELEMENT_SIZE = new Dimension(400,125);
85 static final private Dimension RENAME_ELEMENT_SIZE = new Dimension(400, 95);
86 static final private Dimension ADD_SET_SIZE = new Dimension(400,150);
87 static final private Dimension RENAME_SET_SIZE = new Dimension(400,120);
88 static final private Dimension OPEN_SETS_SIZE = new Dimension(400,135);
89 static final private Dimension ADD_OR_EDIT_ATTRIBUTE_SIZE = new Dimension(600,325);
90 static final private Dimension COMPONENT_SIZE = new Dimension(300,30);
91 static final private Dimension SIZE = new Dimension(800,480);
92 static final private String BLANK = "blank";
93 static final private String ELEMENT = "element";
94 static final private String SET = "set";
95
96 static final public String METADATA_SET_TEMPLATE = "xml" + File.separator + "template.mds";
97
98 //all of our popup menu items
99 static final public int T_COLLECTION = 0;
100 static final public int T_ELEMENT = 1;
101 static final public int T_SET = 4;
102
103 //static final public String MAX_LOADED_SETS = 64;
104 static public Configuration config = null;
105 private MetadataSetManager msm = new MetadataSetManager(this);
106
107 public AddElementActionListener add_element_action_listener = null;
108 public AddSetActionListener add_set_action_listener = null;
109 /** The class used to handle add or edit attribute actions has to be globally available so that we can dispose of its dialog properly. */
110 public AddOrEditAttributeActionListener add_or_edit_attribute_action_listener = null;
111 private boolean ignore = false;
112 /** A card layout is used to switch between the two differing detail views. */
113 private CardLayout card_layout = null;
114
115 /** Um, the size of the screen I'd guess. */
116 private Dimension screen_size = null;
117 private ElementWrapper current_element = null;
118 /** A reference to ourselves so our inner classes can dispose of us. */
119 private GEMS self = null;
120 private String gsdl_path = null;
121 private int current_attribute = -1;
122 private int current_attribute_type = -1;
123
124 //private JLabel element_name = null;
125 private JLabel set_name = null;
126 private JScrollPane element_attributes_scroll = null;
127 private JScrollPane set_attributes_scroll = null;
128 private JPanel details_pane = null;
129 private GEMSModel model = null;
130 private GEMSNode current_node = null;
131 private MetadataSet current_set = null;
132 public RemoveSetActionListener remove_set_action_listener;
133 private SmarterTable element_attributes = null;
134 private SmarterTable set_attributes = null;
135 public org.w3c.dom.Element rootelement;
136
137 //PopupListener provides right-click functionality to any component that needs it
138 //It is a centralized manager for all popups, then we use evt.Source() and determine where the
139 //event was performed
140 private PopupListener popupListener = null;
141
142 /** A tree that represents the current metadata sets associated with this collection. */
143 private SmarterTree mds_tree = null;
144 private String dialog_options[] = null;
145 private boolean atLeastOneSetChanged = false;
146
147 static public void main(String[] args)
148 {
149 // Parse arguments
150 GetOpt go = new GetOpt(args);
151
152 if (go.debug) {
153 DebugStream.enableDebugging();
154
155 Calendar now = Calendar.getInstance();
156 String debug_file_path = "debug" + now.get(Calendar.DATE) + "-" + now.get(Calendar.MONTH) + "-" + now.get(Calendar.YEAR) + ".txt";
157
158 // Debug file is created in the GLI directory
159 DebugStream.println("Debug file path: " + debug_file_path);
160 DebugStream.setDebugFile(debug_file_path);
161 }
162
163 GEMS GEMS;
164 GEMS = new GEMS(go.gsdl_path);
165 }
166
167
168 /** Constructor.
169 * @param set a MetadataSet that should be initially selected
170 * @param action a systematic action that should be performed
171 */
172 public GEMS(String gsdl_path)
173 {
174 //Load configuration file
175 this.self = this;
176 Utility.initImages(this);
177 config = new Configuration(gsdl_path, null, null);
178
179 this.dialog_options = new String[2];
180 this.screen_size = config.screen_size;
181 this.gsdl_path = gsdl_path;
182
183 // Initialise some common images
184 popupListener = new PopupListener(this);
185
186 // Load help
187 HelpFrame help = new HelpFrame();
188
189 dialog_options[0] = Dictionary.get("General.OK");
190 dialog_options[1] = Dictionary.get("General.Cancel");
191
192 // Load all the core metadata sets (in the GLI "metadata" directory)
193 model = new GEMSModel();
194 File metadata_directory = new File(Utility.METADATA_DIR);
195 if (metadata_directory.exists()) {
196 // Load just those .mds files in this directory, and return them
197 File[] directory_files = metadata_directory.listFiles();
198 for (int i = 0; i < directory_files.length; i++) {
199 File child_file = directory_files[i];
200 if (!child_file.isDirectory() && child_file.getName().endsWith(".mds")) {
201 System.err.println("Found mds file: " + child_file);
202 MetadataSet metadata_set = msm.loadMetadataSet(child_file);
203 model.add(null, metadata_set, GEMSNode.SET);
204 }
205 }
206 }
207
208 // Creation
209 setDefaultCloseOperation(DISPOSE_ON_CLOSE);
210 setSize(SIZE);
211 setJMenuBar(new GEMSMenuBar());
212 Dictionary.setText(this, "GEMS.Title");
213
214 JPanel content_pane = (JPanel) getContentPane();
215 content_pane.setBackground(config.getColor("coloring.collection_heading_background", false));
216 JPanel upper_pane = new JPanel();
217 upper_pane.setOpaque(false);
218 JPanel set_details_pane = new JPanel();
219 set_details_pane.setOpaque(false);
220 JPanel set_name_pane = new JPanel();
221 set_name_pane.setOpaque(false);
222 JLabel set_name_label = new JLabel();
223 set_name_label.setOpaque(false);
224 JPanel element_details_pane = new JPanel();
225 element_details_pane.setOpaque(false);
226 JPanel element_inner_pane = new JPanel();
227 element_inner_pane.setOpaque(false);
228 JPanel blank_pane = new JPanel(); // Some blank panel
229 blank_pane.setOpaque(false);
230
231 details_pane = new JPanel();
232 details_pane.setOpaque(false);
233 card_layout = new CardLayout();
234 set_name = new JLabel();
235
236 JPanel mds_tree_pane = new JPanel();
237 mds_tree_pane.setOpaque(false);
238 mds_tree_pane.setPreferredSize(new Dimension(300,500));
239
240 mds_tree = new SmarterTree(model);
241 mds_tree.setCellRenderer(new GEMSTreeCellRenderer());
242 mds_tree.setRootVisible(false);
243 mds_tree.setBackground(config.getColor("coloring.collection_tree_background", false));
244 mds_tree.setForeground(config.getColor("coloring.collection_tree_foreground", false));
245 mds_tree.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
246 mds_tree.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
247 //add popupevent handler for tree items
248 mds_tree.addMouseListener(popupListener);
249 mds_tree.addKeyListener(new KeyPressedHandler());
250 mds_tree.addTreeSelectionListener(new MDSTreeSelectionListener());
251
252 JPanel set_attributes_pane = new JPanel();
253 set_attributes_pane.setOpaque(false);
254 set_attributes_scroll = new JScrollPane();
255 set_attributes_scroll.getViewport().setBackground(config.getColor("coloring.collection_tree_background", false));
256 set_attributes_scroll.setOpaque(true);
257 set_attributes = new SmarterTable();
258 set_attributes.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
259 set_attributes.setBackground(config.getColor("coloring.collection_tree_background", false));
260 set_attributes.setForeground(config.getColor("coloring.collection_tree_foreground", false));
261 set_attributes.setHeadingBackground(config.getColor("coloring.collection_heading_background", false));
262 set_attributes.setHeadingForeground(config.getColor("coloring.collection_heading_foreground", false));
263 set_attributes.setOpaque(false);
264 set_attributes.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
265 set_attributes.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
266 set_attributes.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
267 set_attributes.addMouseListener(popupListener);
268 set_attributes.addMouseListener(new AddOrEditAttributeActionListener());
269 set_attributes.addKeyListener(new RemoveAttributeActionListener()); //Listen for DELETE key
270 set_attributes.getSelectionModel().addListSelectionListener(new AttributesListSelectionListener(set_attributes));
271
272 JPanel element_attributes_pane = new JPanel();
273 element_attributes_pane.setOpaque(false);
274 element_attributes_scroll = new JScrollPane();
275 element_attributes_scroll.getViewport().setBackground(config.getColor("coloring.collection_tree_background", false));
276 element_attributes_scroll.setOpaque(true);
277 element_attributes = new SmarterTable();
278 element_attributes.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
279 element_attributes.setBackground(config.getColor("coloring.collection_tree_background", false));
280 element_attributes.setForeground(config.getColor("coloring.collection_tree_foreground", false));
281 element_attributes.setHeadingBackground(config.getColor("coloring.collection_heading_background", false));
282 element_attributes.setHeadingForeground(config.getColor("coloring.collection_heading_foreground", false));
283 element_attributes.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
284 element_attributes.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
285 element_attributes.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
286 element_attributes.addMouseListener(popupListener);
287 element_attributes.addMouseListener(new AddOrEditAttributeActionListener());
288 element_attributes.addKeyListener(new RemoveAttributeActionListener()); //For the DELETE key
289 element_attributes.getSelectionModel().addListSelectionListener(new AttributesListSelectionListener(element_attributes));
290
291 add_element_action_listener = new AddElementActionListener();
292 add_set_action_listener = new AddSetActionListener();
293 add_or_edit_attribute_action_listener = new AddOrEditAttributeActionListener();
294 remove_set_action_listener = new RemoveSetActionListener();
295
296 // Layout
297 mds_tree_pane.setLayout(new BorderLayout());
298 mds_tree_pane.add(new JScrollPane(mds_tree), BorderLayout.CENTER);
299
300 //Set panes
301 set_name_pane.setLayout(new BorderLayout());
302 set_name_pane.add(set_name_label, BorderLayout.WEST);
303 set_name_pane.add(set_name, BorderLayout.CENTER);
304
305 set_attributes_scroll.setViewportView(set_attributes);
306 set_attributes_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(Dictionary.get("GEMS.Attributes")), BorderFactory.createEmptyBorder(2,2,2,2)));
307 set_attributes_pane.setLayout(new BorderLayout());
308 set_attributes_pane.add(set_attributes_scroll, BorderLayout.CENTER);
309
310 set_details_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(Dictionary.get("GEMS.Set_Details")), BorderFactory.createEmptyBorder(2,2,2,2)));
311 set_details_pane.setLayout(new BorderLayout());
312 set_details_pane.add(set_name_pane, BorderLayout.NORTH);
313 set_details_pane.add(set_attributes_pane, BorderLayout.CENTER);
314
315 //Element panes
316 element_attributes_scroll.setViewportView(element_attributes);
317 element_attributes_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(Dictionary.get("GEMS.Attributes")), BorderFactory.createEmptyBorder(2,2,2,2)));
318 element_attributes_pane.setLayout(new BorderLayout());
319 element_attributes_pane.add(element_attributes_scroll, BorderLayout.CENTER);
320
321 element_inner_pane.setLayout(new BorderLayout());
322 element_inner_pane.add(element_attributes_pane);
323
324 element_details_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(Dictionary.get("GEMS.Element_Details")), BorderFactory.createEmptyBorder(2,2,2,2)));
325 element_details_pane.setLayout(new BorderLayout());
326 element_details_pane.add(element_inner_pane, BorderLayout.CENTER);
327
328 //General panes
329 details_pane.setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
330 details_pane.setLayout(card_layout);
331 details_pane.add(blank_pane, BLANK);
332 details_pane.add(set_details_pane, SET);
333 details_pane.add(element_details_pane, ELEMENT);
334
335 upper_pane.setLayout(new BorderLayout());
336 upper_pane.add(mds_tree_pane, BorderLayout.WEST);
337 upper_pane.add(details_pane, BorderLayout.CENTER);
338
339 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
340 content_pane.setLayout(new BorderLayout());
341 content_pane.add(upper_pane, BorderLayout.CENTER);
342
343 // initialise the selection
344 mds_tree.setSelectionRow(0);
345 // Display
346 setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
347 setVisible(true);
348 }
349
350
351 private void exit()
352 {
353 if(atLeastOneSetChanged == true)
354 {
355 int result = JOptionPane.showConfirmDialog(self, Dictionary.get("GEMS.Confirm_Exit_Save", Dictionary.get("GEMS.Element")), Dictionary.get("GEMS.Confirm_Exit_Save_Title"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
356
357 if(result == 0)
358 {
359 DebugStream.closeDebugStream();
360 msm.save();
361 System.exit(0);
362 }
363 else if(result == 1)
364 {
365 DebugStream.closeDebugStream();
366 System.exit(0);
367 }
368 else if(result == 2)
369 {
370 //do nothing
371 }
372 }
373 else
374 {
375 //Just exit
376 DebugStream.closeDebugStream();
377 System.exit(0);
378 }
379 }
380
381
382
383 private class GEMSMenuBar
384 extends JMenuBar
385 implements ActionListener
386 {
387 private JMenu file = null;
388 private JMenu edit = null;
389 private JMenu help = null;
390
391 public JMenuItem file_exit = null;
392 public JMenuItem file_new = null;
393 public JMenuItem file_open = null;
394 public JMenuItem file_save = null;
395 public JMenuItem edit_copy = null;
396 public JMenuItem edit_cut = null;
397 public JMenuItem edit_paste = null;
398 public JMenuItem help_help = null;
399 public JMenuItem file_delete = null;
400 public JMenuItem file_preferences = null;
401 public GEMSMenuBar()
402 {
403 file = new JMenu();
404 file.setMnemonic(KeyEvent.VK_F);
405 Dictionary.registerText(file, "Menu.File");
406
407 file_exit = new JMenuItem();
408 file_exit.addActionListener(this);
409 file_exit.setMnemonic(KeyEvent.VK_X);
410 Dictionary.registerText(file_exit, "Menu.File_Exit");
411
412 file_new = new JMenuItem();
413 file_new.addActionListener(this);
414 file_new.setMnemonic(KeyEvent.VK_N);
415 Dictionary.registerText(file_new, "Menu.File_New");
416
417 file_open = new JMenuItem();
418 file_open.addActionListener(this);
419 file_open.setMnemonic(KeyEvent.VK_O);
420 Dictionary.registerText(file_open, "Menu.File_Open");
421
422 file_save = new JMenuItem();
423 file_save.addActionListener(this);
424 file_save.setMnemonic(KeyEvent.VK_S);
425 Dictionary.registerText(file_save, "Menu.File_Save");
426
427 file_delete = new JMenuItem();
428 file_delete.addActionListener(new KeyPressedHandler()); //KeyPressedHandler handles deleting stuff.
429 file_delete.setMnemonic(KeyEvent.VK_S);
430 Dictionary.registerText(file_delete, "Menu.File_Delete");
431
432 file_preferences = new JMenuItem();
433 file_preferences.addActionListener(this);
434 file_preferences.setMnemonic(KeyEvent.VK_S);
435 Dictionary.registerText(file_preferences, "Menu.File_Options");
436
437 // Layout (file menu)
438 file.add(file_new);
439 file.add(file_open);
440 file.add(file_save);
441 file.add(file_delete);
442 file.add(new JSeparator());
443 file.add(file_preferences);
444 file.add(new JSeparator());
445 file.add(file_exit);
446
447 // Edit menu
448 edit = new JMenu();
449 edit.setMnemonic(KeyEvent.VK_E);
450 Dictionary.registerText(edit, "Menu.Edit");
451
452 edit_cut = new JMenuItem();
453 edit_cut.addActionListener(this);
454 edit_cut.setMnemonic(KeyEvent.VK_X);
455 Dictionary.registerText(edit_cut, "Menu.Edit_Cut");
456
457 edit_copy = new JMenuItem();
458 edit_copy.addActionListener(this);
459 edit_copy.setMnemonic(KeyEvent.VK_C);
460 Dictionary.registerText(edit_copy, "Menu.Edit_Copy");
461
462 edit_paste = new JMenuItem();
463 edit_paste.addActionListener(this);
464 edit_paste.setMnemonic(KeyEvent.VK_V);
465 Dictionary.registerText(edit_paste, "Menu.Edit_Paste");
466
467 // Layout (edit menu)
468 edit.add(edit_cut);
469 edit.add(edit_copy);
470 edit.add(edit_paste);
471
472 // Help menu. Is not used! --Matthew
473 help = new JMenu();
474 help.setIcon(Utility.HELP_ICON);
475 Dictionary.setText(help, "Menu.Help");
476
477 help_help = new JMenuItem();
478 help_help.addActionListener(this);
479 Dictionary.registerText(help_help, "Menu.Help");
480
481 // Layout (help menu)
482 help.add(help_help);
483
484 // Layout (menu bar)
485 this.add(file);
486 this.add(Box.createHorizontalStrut(15));
487 this.add(edit);
488 this.add(Box.createHorizontalGlue());
489 //this.add(help);
490 }
491
492
493 public void actionPerformed(ActionEvent event)
494 {
495 Object event_source = event.getSource();
496
497 // File -> New
498 if (event_source == file_new) {
499 AddSetActionListener rah = new AddSetActionListener();
500 rah.setVisible(true);
501 // rah.show();
502
503 return;
504 }
505
506 // File -> Open
507 if (event_source == file_open) {
508
509 //we first launch the dialog to determine where the jfilechooser should be opened
510 //ie: for collection specific sets - attila dec10-04
511 String set_directory = Utility.METADATA_DIR;
512
513 SetSelectionDialog m = new SetSelectionDialog();
514 m.setVisible(true);
515 // m.show();
516
517 //once we have clicked 'ok' on the jdialog above, then we should have
518 //the directory pointer in string set_directory...and pass it to the jfilechoose constru
519 return;
520 }
521
522 // File -> Save
523 if (event_source == file_save) {
524 msm.save();
525 atLeastOneSetChanged = false;
526 return;
527 }
528
529 // File -> Exit
530 if (event_source == file_exit) {
531 exit(); //The exit() method checks if data needs saving.
532 }
533
534 // File -> Preferences
535 if(event_source == file_preferences){
536 GEMSPreferences GemsPreferences = new GEMSPreferences();
537 }
538
539 // Edit -> Cut
540 if (event_source == edit_cut) {
541 try {
542 KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
543 // Get the component with selected text as a JTextComponent
544 JTextComponent text = (JTextComponent) kfm.getPermanentFocusOwner();
545 // Cut the text to the clipboard
546 text.cut();
547 }
548 catch (ClassCastException cce) {
549 // If the component is not a text component ignore the cut command
550 DebugStream.println(cce.toString());
551 }
552 return;
553 }
554
555 // Edit -> Copy
556 if (event_source == edit_copy) {
557 try {
558 KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
559 // Get the component with selected text as a JTextComponent
560 JTextComponent text = (JTextComponent) kfm.getPermanentFocusOwner();//getFocusOwner();
561 text.copy();
562 }
563 catch (Exception cce) {
564 // If the component is not a text component ignore the copy command
565 DebugStream.println(cce.toString());
566 }
567 return;
568 }
569
570 // Edit -> Paste
571 if (event_source == edit_paste) {
572 try {
573 KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
574 // Get the component with selected text as a JTextComponent
575 JTextComponent text = (JTextComponent) kfm.getPermanentFocusOwner();
576 // Cut the text to the clipboard
577 text.paste();
578 }
579 catch (ClassCastException cce) {
580 // If the component is not a text component ignore the paste command
581 DebugStream.println(cce.toString());
582 }
583 return;
584 }
585
586 // Help -> Help
587 if (event_source == help_help) {
588 HelpFrame.setView("editingmetadatasets");
589 return;
590 }
591 }
592 }
593
594
595 private class MetadataSetFileFilter
596 extends FileFilter
597 {
598 public boolean accept(File file)
599 {
600 String file_name = file.getName().toLowerCase();
601 return(file_name.endsWith(".mds") || file_name.indexOf(".") == -1);
602 }
603
604 public String getDescription()
605 {
606 return Dictionary.get("MetadataSet.Files");
607 }
608 }
609
610
611 private class ActionTask
612 extends Thread {
613 private int action;
614 public ActionTask(int action) {
615 this.action = action;
616 }
617 public void run() {
618 boolean complete = false;
619 while(!complete) {
620 if(self.isVisible()) {
621 switch(action) {
622 case ADD_SET:
623 add_set_action_listener.actionPerformed(new ActionEvent(this, 0, "Blarg!"));
624 break;
625 case REMOVE_SET:
626 if(!mds_tree.isSelectionEmpty()) {
627 remove_set_action_listener.actionPerformed(new ActionEvent(this, 0, "Blarg!"));
628 }
629 break;
630 }
631 complete = true;
632 }
633 else {
634 try {
635 synchronized(this) {
636 wait(100);
637 }
638 }
639 catch(Exception exception) {
640 }
641 }
642 }
643 }
644 }
645 //callback method
646 protected void processWindowEvent(WindowEvent evt){
647
648 if(evt.getID() == WindowEvent.WINDOW_CLOSING){
649
650 exit();
651 }
652 }
653 //called from MetadataSetManager...I don't think it should be here anymore, but for now it's ok
654
655 public void warn_cant_load_set(){
656 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Already_Loaded_Set_Error"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
657 }
658 public void dispose() {
659
660
661 //if anything has changed, warn user that they should save
662 if(atLeastOneSetChanged == true) {
663
664 int result = JOptionPane.showOptionDialog(self, Dictionary.get("GEMS.Confirm_Exit_Save", Dictionary.get("GEMS.Element")), Dictionary.get("GEMS.Confirm_Exit_Save_Title"), JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dialog_options, dialog_options[0]);
665 // System.out.println("Exit: "+result);
666 if(result == 0) {
667 msm.save();
668 }
669 }
670 atLeastOneSetChanged = false;
671 // Destructor
672 card_layout = null;
673 screen_size = null;
674 self = null;
675 details_pane = null;
676 element_attributes = null;
677 set_attributes = null;
678 set_name = null;
679 mds_tree = null;
680
681 popupListener = null;
682 // Dispose of inner dialogs
683 if (add_element_action_listener != null) {
684 add_element_action_listener.dispose();
685 add_element_action_listener = null;
686 }
687 if (add_or_edit_attribute_action_listener != null) {
688 add_or_edit_attribute_action_listener.dispose();
689 add_or_edit_attribute_action_listener = null;
690 }
691 remove_set_action_listener = null;
692
693 //close
694 super.dispose();
695 }
696
697
698 /**
699 Class to handle adding or modifying element attributes.
700 */
701 private class AddOrEditAttributeActionListener
702 extends ModalDialog
703 implements ActionListener, MouseListener {
704 private boolean add_type = true;
705 private ComboArea value = null;
706 private JButton cancel_button = null;
707 private JButton ok_button = null;
708 private JComboBox language_box = null;
709 private GComboBox name = null;
710 private HashMap name_to_values = null;
711 private JLabel target = null;
712 private JLabel target_label = null;
713 private Vector attributeLists = null;
714
715 org.w3c.dom.Document lang = Utility.parse(Configuration.gsdl_path + File.separator + "gli" + File.separator + "classes" + File.separator + "xml" + File.separator + "languages.xml", false);
716
717 /** Constructor. */
718 public AddOrEditAttributeActionListener() {
719 super(self);
720 setModal(true);
721 attributeLists = new Vector();
722 attributeLists.add("identifier");
723 attributeLists.add("comment");
724 attributeLists.add("definition");
725 attributeLists.add("name");
726
727 attributeLists.add("creator");
728 attributeLists.add("date");
729 attributeLists.add("contact");
730 attributeLists.add("family");
731
732 attributeLists.add("lastchanged");
733 attributeLists.add("language_dependant");
734 attributeLists.add("version");
735 attributeLists.add("datatype");
736
737 attributeLists.add("obligation");
738 attributeLists.add("maximum_occurence");
739 attributeLists.add("registration_authority");
740
741 setSize(ADD_OR_EDIT_ATTRIBUTE_SIZE);
742 name_to_values = new HashMap();
743
744 // Creation
745 JPanel content_pane = (JPanel) getContentPane();
746 content_pane.setBackground(config.getColor("coloring.collection_heading_background", false));
747 JPanel upper_pane = new JPanel();
748 upper_pane.setOpaque(false);
749
750 JPanel labels_pane = new JPanel();
751 JPanel boxes_pane = new JPanel();
752
753 target_label = new JLabel();
754 target_label.setOpaque(false);
755 target = new JLabel();
756 target.setOpaque(false);
757
758 JLabel name_label = new JLabel();
759 name_label.setOpaque(false);
760 Dictionary.setText(name_label, "GEMS.Name");
761 name = new GComboBox();
762 name.setEditable(true);
763 Dictionary.setTooltip(name, "GEMS.Attribute_Name_Tooltip");
764
765 JLabel language_label = new JLabel();
766 language_label.setOpaque(false);
767 Dictionary.setText(language_label, "GEMS.Language");
768 language_box = new JComboBox();
769
770 for(int n = 0; n < attributeLists.size(); n++){
771 name.add(attributeLists.get(n));
772 }
773
774 Dictionary.setTooltip(language_box, "GEMS.Attribute_Language_Tooltip");
775
776 JPanel center_pane = new JPanel();
777 center_pane.setOpaque(false);
778 value = new ComboArea(Dictionary.get("GEMS.Values"), COMPONENT_SIZE);
779 value.setOpaque(false);
780
781 JTextArea v_text_area = (JTextArea) value.getTextComponent();
782 v_text_area.setBackground(config.getColor("coloring.collection_tree_background", false));
783 v_text_area.setForeground(config.getColor("coloring.collection_tree_foreground", false));
784 v_text_area.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
785 v_text_area.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
786 Dictionary.setTooltip(v_text_area, "GEMS.Attribute_Value_Tooltip");
787
788 JPanel button_pane = new JPanel();
789 button_pane.setOpaque(false);
790 ok_button = new GLIButton();
791 ok_button.setMnemonic(KeyEvent.VK_O);
792 getRootPane().setDefaultButton(ok_button);
793 Dictionary.setBoth(ok_button, "General.OK", "General.OK_Tooltip");
794 cancel_button = new GLIButton();
795 cancel_button.setMnemonic(KeyEvent.VK_C);
796 Dictionary.setBoth(cancel_button, "General.Cancel", "General.Pure_Cancel_Tooltip");
797
798 // Connection
799 TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
800 cancel_button.addActionListener(this);
801 name.addActionListener(this);
802 ok_button.addActionListener(this);
803 ok_button_enabler.add((JTextComponent)name.getEditor()); // Assuming the default editor is a JTextField!
804
805 // Layout
806 labels_pane.setLayout(new GridLayout(3,1,0,5));
807 labels_pane.add(target_label);
808 labels_pane.add(name_label);
809 labels_pane.add(language_label);
810
811 boxes_pane.setLayout(new GridLayout(3,1,0,5));
812 boxes_pane.add(target);
813 boxes_pane.add(name);
814 boxes_pane.add(language_box);
815
816 upper_pane.setLayout(new BorderLayout(5,0));
817 upper_pane.add(labels_pane, BorderLayout.WEST);
818 upper_pane.add(boxes_pane, BorderLayout.CENTER);
819
820 value.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
821
822 button_pane.setLayout(new GridLayout(1,2,5,0));
823 button_pane.add(ok_button);
824 button_pane.add(cancel_button);
825
826 center_pane.setLayout(new BorderLayout());
827 center_pane.add(value, BorderLayout.CENTER);
828 center_pane.add(button_pane, BorderLayout.SOUTH);
829
830 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
831 content_pane.setLayout(new BorderLayout());
832 content_pane.add(upper_pane, BorderLayout.NORTH);
833 content_pane.add(center_pane, BorderLayout.CENTER);
834
835 setLocation((config.screen_size.width - ADD_OR_EDIT_ATTRIBUTE_SIZE.width) / 2, (config.screen_size.height - ADD_OR_EDIT_ATTRIBUTE_SIZE.height) / 2);
836
837 GEMSLanguageManager GemsLangManager = new GEMSLanguageManager(Configuration.gsdl_path + File.separator + "gli" + File.separator + "classes" + File.separator + "xml" + File.separator + "languages.xml");
838
839 Vector languagecodes = GemsLangManager.getLanguageCodes();
840
841 for(int p = 0; p < languagecodes.size(); p++){
842
843 language_box.addItem(languagecodes.get(p).toString());
844 }
845
846 String code = Configuration.getLanguage();
847 language_box.setSelectedItem(code);
848 }
849
850 //Handle double clicks in the table.
851 public void mouseClicked(MouseEvent e)
852 {
853 if(e.getSource() == element_attributes || e.getSource() == set_attributes)
854 {
855 if(e.getClickCount() == 2) //Double click
856 {
857 //Show the Edit Attribute dialog
858 this.menuEditValue();
859 this.editAttribute();
860 }
861 }
862 }
863 //These methods are required by interface MouseListener
864 public void mouseEntered(MouseEvent e){}
865 public void mouseExited(MouseEvent e){}
866 public void mousePressed(MouseEvent e){}
867 public void mouseReleased(MouseEvent e){}
868
869 /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to add a new attribute to the selected set or element.
870 * @param event An <strong>ActionEvent</strong> containing information about the event.
871 */
872 public void actionPerformed(ActionEvent event) {
873 Object source = event.getSource();
874 AttributeTableModel model = null;
875
876 if(current_element != null)
877 {
878 target.setText(current_element.getName());
879 Dictionary.setText(target_label, "GEMS.Target");
880 }
881 else if(current_set != null)
882 {
883 Dictionary.setText(target_label, "GEMS.Set");
884 target.setText(current_set.toString());
885 Dictionary.setText(target_label, "GEMS.Target");
886 }
887
888 if (source == popupListener.menuEditValue)
889 {
890 this.menuEditValue();
891 }
892
893 if(source == ok_button) {
894 boolean success = true;
895
896 // Add or edit a set/element attribute
897 switch(current_attribute_type) {
898 case GEMSNode.SET:
899 model = (AttributeTableModel) set_attributes.getModel();
900 success = addOrEditSetAttribute(model);
901 break;
902 case GEMSNode.ELEMENT:
903 model = (AttributeTableModel) element_attributes.getModel();
904 success = addOrEditElementAttribute(model);
905 break;
906 }
907
908 if (success) {
909 // Hide dialog
910 atLeastOneSetChanged = true;
911 setVisible(false);
912 return;
913 }
914 else
915 {
916 //If no success (an attribute with that name already exists), do nothing.
917 }
918 }
919 else if(source == cancel_button) {
920 // Hide dialog
921 setVisible(false);
922 return;
923 }
924 else if(source == name) {
925 //System.err.println("source is name");
926 Object object = name.getSelectedItem();
927 if(object != null) {
928 java.util.List values = (java.util.List) name_to_values.get(object.toString());
929
930 if(value != null && values != null){
931 value.clear();
932 for(int i = 0; i < values.size(); i++) {
933 value.add(values.get(i));
934 }
935 }
936 }
937 }
938 else if (source == popupListener.menuAddAttributeAttribute || source == popupListener.menuAddAttributeSet || source == popupListener.menuAddAttributeElement){
939
940 Dictionary.setText(this, "GEMS.Add_Attribute");
941 for(int i = 0; i < attributeLists.size(); i++) {
942 name.add(attributeLists.get(i).toString());
943
944 }
945 name.setEnabled(true);
946 setVisible(true);
947 }
948
949 else if(current_attribute != -1) {
950 this.editAttribute();
951 }
952
953 source = null;
954 }
955
956 private void menuEditValue()
957 {
958 AttributeTableModel tablemodel = null;
959
960 String prevLang = new String("");
961 String prevValue = new String("");
962
963 add_type = false;
964 //grab the table model based on what is currently selected
965 switch(current_attribute_type) {
966 case GEMSNode.SET:
967 tablemodel = (AttributeTableModel) set_attributes.getModel();
968 //grab value in table
969 prevLang = tablemodel.getValueAt(current_attribute,0).toString();
970 prevValue = tablemodel.getValueAt(current_attribute,1).toString();
971
972 break;
973 case GEMSNode.ELEMENT:
974 tablemodel = (AttributeTableModel) element_attributes.getModel();
975 //grab values in table( lang and value)
976 prevLang = tablemodel.getValueAt(current_attribute,1).toString();
977 prevValue = tablemodel.getValueAt(current_attribute,2).toString();
978
979 break;
980 default:
981 //by default grab element_attr's
982 tablemodel = (AttributeTableModel) element_attributes.getModel();
983 prevLang = tablemodel.getValueAt(current_attribute,1).toString();
984 prevValue = tablemodel.getValueAt(current_attribute,2).toString();
985
986 break;
987 }
988 language_box.setEnabled(false);
989
990 //if a set attr is selected, then do not do any lang operations, other than setting index to -1
991 if(current_attribute_type != GEMSNode.SET) {
992
993 //set the current language to show up in language_box(no lang if no lang specified)
994 if(prevLang == null || prevLang.compareTo(" ")==0 || prevLang.compareTo("") == 0 || prevLang.compareTo(" ")==0) {
995 language_box.setSelectedIndex(-1);
996
997 }
998 else {
999 language_box.setSelectedItem(prevLang.toLowerCase());
1000 }
1001 }// end currattr != GEMSnode.set
1002 else {
1003
1004 language_box.setSelectedIndex(-1);
1005
1006 }// end currattr == GEMSnode.set
1007 value.setText(prevValue);
1008 }
1009
1010 private void editAttribute()
1011 {
1012 //System.err.println("just entered editAttribute"); //debug
1013 AttributeTableModel model = null;
1014 Dictionary.setText(this, "GEMS.Edit_Attribute");
1015
1016 switch(current_attribute_type) {
1017 case GEMSNode.ELEMENT:
1018 model = (AttributeTableModel) element_attributes.getModel();
1019 break;
1020 case GEMSNode.SET:
1021 model = (AttributeTableModel) set_attributes.getModel();
1022 break;
1023 }
1024 add_type = false;
1025 String name_str = (String) model.getValueAt(current_attribute, 0);
1026 String value_str = (String) model.getValueAt(current_attribute, model.getColumnCount() - 1);
1027 model = null;
1028 // Retrieve the appropriate value model
1029 java.util.List values = (java.util.List) name_to_values.get(name_str);
1030 // Only possible for collection file selections.
1031 if(values == null) {
1032 values = msm.getElements();
1033 }
1034 name.setSelectedItem(name_str);
1035 name_str = null;
1036 for(int i = 0; i < values.size(); i++) {
1037 Object temp_value = values.get(i);
1038 if(temp_value instanceof ElementWrapper) {
1039 value.add(new NameElementWrapperEntry(temp_value));
1040 }
1041 else {
1042 value.add(temp_value);
1043 }
1044 }
1045 values = null;
1046 value.setSelectedItem(value_str);
1047 value_str = null;
1048 setVisible(true);
1049 }
1050
1051 private boolean addOrEditSetAttribute(AttributeTableModel model)
1052 {
1053 String new_name_str = name.getSelectedItem().toString();
1054 String value_str = Codec.transform(Codec.transformUnicode(value.getText()), Codec.TEXT_TO_DOM);
1055 String old_name_str = null;
1056 boolean cont = false;
1057 boolean edit = false;
1058
1059 if(!add_type && current_attribute != -1) //If edit, grab the attribute's old name
1060 {
1061 old_name_str = (String) set_attributes.getValueAt(current_attribute, 0);
1062 edit = true;
1063 }
1064
1065 // Check that there isn't already an entry for this attribute
1066 if (!model.contains(new_name_str, 0) || (edit && new_name_str.equals(old_name_str)))
1067 {
1068 if(edit) //If edit, remove old attribute
1069 {
1070 current_set.removeAttribute(old_name_str);
1071 model.removeRow(current_attribute);
1072 }
1073
1074 // Add the new attribute
1075 current_set.addAttribute(new_name_str, value_str);
1076 // Update the attribute table
1077 model.add(new Attribute(new_name_str, value_str));
1078 cont = true;
1079 }
1080 // Otherwise show an error message and do not proceed
1081 else
1082 {
1083 cont = false;
1084 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Attribute_Already_Exists"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
1085 }
1086
1087 value_str = null;
1088 new_name_str = null;
1089 return cont;
1090 }
1091
1092
1093 private boolean addOrEditElementAttribute(AttributeTableModel model)
1094 {
1095 String new_name_str = name.getSelectedItem().toString();
1096 String old_name_str = null;
1097 String language_code = (String) language_box.getSelectedItem();
1098 String value_str = Codec.transform(Codec.transformUnicode(value.getText()), Codec.TEXT_TO_DOM);
1099 String old_value_str = null;
1100 String old_lang_code = null;
1101 boolean cont = false;
1102 boolean edit = false;
1103
1104 if(!add_type && current_attribute != -1) //An edit
1105 {
1106 Attribute old_attribute = model.getAttribute(current_attribute);
1107 old_value_str = old_attribute.value;
1108 old_lang_code = old_attribute.language;
1109 old_name_str = (String) element_attributes.getValueAt(current_attribute, 0); //get the old name.
1110 edit = true;
1111 }
1112
1113 //Check that there isn't already an entry for this attribute
1114 if (!model.contains(new_name_str, 0) || (edit && new_name_str.equals(old_name_str)))
1115 {
1116 if(edit) //If this is an edit, remove the old attribute
1117 {
1118 current_element.removeAttribute(old_name_str, old_lang_code, old_value_str);
1119 model.removeRow(current_attribute);
1120 }
1121
1122 // Add the new attribute
1123 //System.err.println("current_element is: " + current_element.toString()); //debug
1124 current_element.addAttribute(new_name_str, language_code, value_str);
1125 // Update the attribute table
1126 int row = model.add(new Attribute(new_name_str, language_code, value_str));
1127 element_attributes.setRowSelectionInterval(row, row);
1128 cont = true;
1129 }
1130 // Otherwise show an error message and do not proceed
1131 else
1132 {
1133 cont = false;
1134 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Attribute_Already_Exists"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
1135 }
1136
1137 value_str = null;
1138 language_code = null;
1139 new_name_str = null;
1140 return cont;
1141 }
1142 }
1143
1144
1145 private class AddSubelementActionListener extends AddElementActionListener implements ActionListener {
1146
1147 public AddSubelementActionListener() {
1148 Dictionary.setText(this, "GEMS.Add_Subelement");
1149 Dictionary.setTooltip(name_field, "GEMS.Subelement_Name_Tooltip");
1150 }
1151
1152 public void actionPerformed(ActionEvent event)
1153 {
1154 Object source = event.getSource();
1155 current_element = current_node.getElement(); //current_element here is used generically for a element or subelement.
1156
1157 if(source == ok_button) //Add then dispose
1158 {
1159 String name_str = Codec.transform(Codec.transformUnicode(name_field.getText()), Codec.TEXT_TO_DOM);
1160 current_set = msm.getSet(current_element.getNamespace());
1161 if(current_set != null)
1162 {
1163 // If this subelement doesn't already exist.
1164 if(!current_element.containsSubelement(name_str))
1165 {
1166 // Add it,
1167 String language_code = config.getLanguage();
1168 ElementWrapper subelement = current_set.addElement(name_str, language_code, current_node);
1169
1170 final GEMSNode new_node = model.add(current_node, subelement, GEMSNode.ELEMENT); //Then update the tree.
1171
1172 //SwingUtilities.invokeLater is used so that expandPath works on new parents.
1173 SwingUtilities.invokeLater(new Runnable() {
1174 public void run() {
1175 mds_tree.expandPath(new TreePath(current_node.getPath())); //Expand element so can see subelement.
1176 mds_tree.getSelectionModel().setSelectionPath(new TreePath(new_node)); //works, but node on tree doesn't look hilighted!!
1177 }
1178 });
1179
1180 //Done. Finish up.
1181 subelement = null;
1182 setVisible(false);
1183 atLeastOneSetChanged = true; //mark as changed
1184 }
1185 else
1186 {
1187 //A subelement with the same name exists. Display an error message.
1188 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Subelement_Already_Exists"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
1189 }
1190 }
1191 else
1192 {
1193 //This should not happen.
1194 System.err.println("Error: current_set is null in AddSubelementActionListener");
1195 }
1196 }
1197 else if(source == cancel_button)
1198 {
1199 setVisible(false);
1200 }
1201 else
1202 {
1203 set_field.setText(current_node.toString()); //set to the name of the subelement
1204 name_field.setText("");
1205 setVisible(true);
1206 }
1207 }
1208
1209 public void dispose()
1210 {
1211 cancel_button = null;
1212 ok_button = null;
1213 name_field = null;
1214 set_field = null;
1215 super.dispose();
1216 }
1217 }
1218
1219
1220 private class AddElementActionListener
1221 extends ModalDialog
1222 implements ActionListener {
1223 protected JButton cancel_button = null;
1224 protected JButton ok_button = null;
1225 protected JLabel set_field = null;
1226 protected NonWhitespaceField name_field = null;
1227 public AddElementActionListener() {
1228 super(self);
1229 setModal(true);
1230 setSize(ADD_ELEMENT_SIZE);
1231 // Creation
1232 JPanel content_pane = (JPanel) getContentPane();
1233 content_pane.setBackground(config.getColor("coloring.collection_heading_background", false));
1234 JPanel center_pane = new JPanel();
1235 center_pane.setOpaque(false);
1236 Dictionary.setText(this, "GEMS.Add_Element");
1237
1238 JPanel labels_pane = new JPanel();
1239 labels_pane.setOpaque(false);
1240 JLabel set_label = new JLabel();
1241 set_label.setOpaque(false);
1242 Dictionary.setText(set_label, "GEMS.Set");
1243 set_field = new JLabel();
1244 set_field.setOpaque(false);
1245
1246 JPanel values_pane = new JPanel();
1247 values_pane.setOpaque(false);
1248 JLabel name_label = new JLabel();
1249 name_label.setOpaque(false);
1250 Dictionary.setText(name_label, "GEMS.Name");
1251 name_field = new NonWhitespaceField();
1252 name_field.setBackground(config.getColor("coloring.collection_tree_background", false));
1253 name_field.setForeground(config.getColor("coloring.collection_tree_foreground", false));
1254 name_field.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
1255 name_field.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
1256 Dictionary.setTooltip(name_field, "GEMS.Element_Name_Tooltip");
1257
1258 JPanel button_pane = new JPanel();
1259 button_pane.setOpaque(false);
1260
1261 ok_button = new GLIButton();
1262 ok_button.setMnemonic(KeyEvent.VK_O);
1263 getRootPane().setDefaultButton(ok_button);
1264 Dictionary.setBoth(ok_button, "General.OK", "General.OK_Tooltip");
1265 cancel_button = new GLIButton();
1266 cancel_button.setMnemonic(KeyEvent.VK_C);
1267 Dictionary.setBoth(cancel_button, "General.Cancel", "General.Pure_Cancel_Tooltip");
1268
1269 TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
1270
1271 // Connection
1272 cancel_button.addActionListener(this);
1273 ok_button.addActionListener(this);
1274 ok_button_enabler.add(name_field);
1275
1276 // Layout
1277 labels_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
1278 labels_pane.setLayout(new GridLayout(2,1));
1279 labels_pane.add(set_label);
1280 labels_pane.add(name_label);
1281
1282 values_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
1283 values_pane.setLayout(new GridLayout(2,1));
1284 values_pane.add(set_field);
1285 values_pane.add(name_field);
1286
1287 center_pane.setLayout(new BorderLayout(5,5));
1288 center_pane.add(labels_pane, BorderLayout.WEST);
1289 center_pane.add(values_pane, BorderLayout.CENTER);
1290
1291 button_pane.setLayout(new GridLayout(1,2,0,5));
1292 button_pane.add(ok_button);
1293 button_pane.add(cancel_button);
1294
1295 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
1296 content_pane.setLayout(new BorderLayout());
1297 content_pane.add(center_pane, BorderLayout.CENTER);
1298 content_pane.add(button_pane, BorderLayout.SOUTH);
1299
1300 setLocation((config.screen_size.width - ADD_ELEMENT_SIZE.width) / 2, (config.screen_size.height - ADD_ELEMENT_SIZE.height) / 2);
1301 }
1302
1303 /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
1304 * @param event An <strong>ActionEvent</strong> containing information about the event.
1305 */
1306 public void actionPerformed(ActionEvent event) {
1307 Object source = event.getSource();
1308 if(source == ok_button) {
1309 // Add then dispose
1310 String name_str = Codec.transform(Codec.transformUnicode(name_field.getText()), Codec.TEXT_TO_DOM);
1311 // If this element doesn't already exist.
1312 if(!current_set.containsElement(name_str)) {
1313 // Add it,
1314 String language_code = config.getLanguage();
1315 ElementWrapper element = current_set.addElement(name_str, language_code, null);
1316
1317 // Then update the tree
1318 model.add(current_node, element, GEMSNode.ELEMENT);
1319 //SwingUtilities.invokeLater is used so that expandPath works on new parents.
1320 SwingUtilities.invokeLater(new Runnable() {
1321 public void run() {
1322 mds_tree.expandPath(new TreePath(current_node.getPath())); //expand set.
1323 }
1324 });
1325
1326 // Done
1327 element = null;
1328 setVisible(false);
1329
1330 //mark as changed
1331 atLeastOneSetChanged = true;
1332 current_set.setSetChanged(true);
1333
1334 }
1335 // Otherwise show an error message and do not proceed.
1336 else {
1337 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Element_Already_Exists"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
1338 }
1339 name_str = null;
1340 }
1341 else if(source == cancel_button) {
1342 // Dispose
1343 setVisible(false);
1344 }
1345 else {
1346 if(current_set != null) { //Does this ever happen? --Matthew
1347 // You can't manually add elements to the Greenstone metadata set.
1348 if(!current_set.getNamespace().equals("")) {
1349 set_field.setText(current_set.toString());
1350 name_field.setText("");
1351 // Display
1352 setVisible(true);
1353 }
1354 // Warn the user that they can't do that dave.
1355 else {
1356
1357 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Cannot_Add_Elements_To_Greenstone_MDS"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
1358 }
1359 }
1360 }
1361 source = null;
1362 }
1363
1364 public void dispose() {
1365 cancel_button = null;
1366 ok_button = null;
1367 name_field = null;
1368 set_field = null;
1369 super.dispose();
1370 }
1371 }
1372
1373
1374 private class AddSetActionListener
1375 extends ModalDialog
1376 implements ActionListener {
1377 private JButton cancel_button = null;
1378 private JButton ok_button = null;
1379 private JTextField name_field = null;
1380 private JTextField namespace_field = null;
1381 private JComboBox existingSetJComboBox = new JComboBox();
1382
1383 public AddSetActionListener() {
1384 super(self);
1385 setModal(true);
1386 setSize(ADD_SET_SIZE);
1387 Dictionary.setText(this, "GEMS.Add_Set");
1388
1389 // Creation
1390 JPanel content_pane = (JPanel) getContentPane();
1391 content_pane.setBackground(config.getColor("coloring.collection_heading_background", false));
1392 JPanel center_pane = new JPanel();
1393 center_pane.setOpaque(false);
1394
1395 JPanel label_pane = new JPanel();
1396 JPanel boxes_pane = new JPanel();
1397
1398 JLabel namespace_label = new JLabel();
1399 namespace_label.setOpaque(false);
1400 Dictionary.setText(namespace_label, "GEMS.Namespace");
1401 namespace_field = TransformCharacterTextField.createNamespaceTextField();
1402 namespace_field.setBackground(config.getColor("coloring.collection_tree_background", false));
1403 namespace_field.setForeground(config.getColor("coloring.collection_tree_foreground", false));
1404 namespace_field.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
1405 namespace_field.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
1406 Dictionary.setTooltip(namespace_field, "GEMS.Set_Namespace_Tooltip");
1407
1408 JLabel name_label = new JLabel();
1409 name_label.setOpaque(false);
1410 Dictionary.setText(name_label, "GEMS.Name");
1411 name_field = new JTextField();
1412 name_field.setBackground(config.getColor("coloring.collection_tree_background", false));
1413 name_field.setForeground(config.getColor("coloring.collection_tree_foreground", false));
1414 name_field.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
1415 name_field.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
1416 Dictionary.setTooltip(name_field, "GEMS.Set_Name_Tooltip");
1417
1418 JPanel button_pane = new JPanel();
1419 button_pane.setOpaque(false);
1420
1421 ok_button = new GLIButton();
1422 ok_button.setMnemonic(KeyEvent.VK_O);
1423 getRootPane().setDefaultButton(ok_button);
1424 Dictionary.setBoth(ok_button, "General.OK", "General.OK_Tooltip");
1425 cancel_button = new GLIButton();
1426 cancel_button.setMnemonic(KeyEvent.VK_C);
1427 Dictionary.setBoth(cancel_button, "General.Cancel", "General.Pure_Cancel_Tooltip");
1428 TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
1429
1430 // Connection
1431 cancel_button.addActionListener(this);
1432 ok_button.addActionListener(this);
1433 ok_button_enabler.add(name_field);
1434 ok_button_enabler.add(namespace_field);
1435
1436 // Layout
1437 label_pane.setLayout(new GridLayout(3,1));
1438 label_pane.add(name_label);
1439 label_pane.add(namespace_label);
1440 boxes_pane.setLayout(new GridLayout(3,1));
1441 boxes_pane.add(name_field);
1442 boxes_pane.add(namespace_field);
1443
1444 JLabel inheritJLabel = new JLabel();
1445 Dictionary.setText(inheritJLabel, "GEMS.inheritMetadataSet");
1446
1447 label_pane.add(inheritJLabel);
1448
1449 int getSetsLen = msm.getSets().toArray().length;
1450 Vector theSets = msm.getSets();
1451
1452 for(int k = 0; k < theSets.size(); k++){
1453 MetadataSet ms = (MetadataSet)theSets.elementAt(k);
1454
1455 existingSetJComboBox.addItem(new String(ms.getName() + " #% " + ms.getFile().toString()));
1456
1457 }
1458 //add sets to existingSetJComboBox
1459
1460 JLabel dummyl = new JLabel();
1461 Dictionary.setText(dummyl, "GEMS.Add_Set.No_Inherit");
1462
1463 existingSetJComboBox.addItem("Do not inherit");
1464 existingSetJComboBox.setSelectedIndex(getSetsLen);
1465 boxes_pane.add(existingSetJComboBox);
1466
1467 center_pane.setLayout(new BorderLayout(5,0));
1468 center_pane.add(label_pane, BorderLayout.WEST);
1469 center_pane.add(boxes_pane, BorderLayout.CENTER);
1470
1471 button_pane.setLayout(new GridLayout(1,2,0,5));
1472 button_pane.add(ok_button);
1473 button_pane.add(cancel_button);
1474
1475 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
1476 content_pane.setLayout(new BorderLayout());
1477 content_pane.add(center_pane, BorderLayout.CENTER);
1478 content_pane.add(button_pane, BorderLayout.SOUTH);
1479
1480 setLocation((config.screen_size.width - ADD_SET_SIZE.width) / 2, (config.screen_size.height - ADD_SET_SIZE.height) / 2);
1481 }
1482
1483 private boolean a_set_exists_with_this_namespace(String namespace){
1484 Vector p = msm.getSets();
1485 boolean flag = false;
1486 for(int k = 0; k < p.size(); k++){
1487 MetadataSet s = (MetadataSet)p.get(k);
1488
1489 if(s.getNamespace().compareTo(namespace) == 0){
1490 flag = true;
1491 }
1492 }
1493
1494 return flag;
1495 }
1496
1497
1498 /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
1499 * @param event An <strong>ActionEvent</strong> containing information about the event.
1500 */
1501 public void actionPerformed(ActionEvent event) {
1502 Object source = event.getSource();
1503
1504 if(source == ok_button) {
1505 //this code below handles whether we inherit from an existing set or not
1506
1507 String namespace_str = namespace_field.getText();
1508 String name_str = Codec.transform(Codec.transformUnicode(name_field.getText()), Codec.TEXT_TO_DOM);
1509
1510 if (existingSetJComboBox.getSelectedItem().toString().trim().compareTo("Do not inherit") == 0){
1511
1512 // Ensure the set doesn't already exist
1513 if(a_set_exists_with_this_namespace(namespace_str) == false){
1514
1515 MetadataSet set = msm.addSet(namespace_str, name_str);
1516
1517 //mark as set changed = true
1518 set.setSetChanged(true);
1519 atLeastOneSetChanged = true;
1520
1521 // Update tree.
1522 model.add(null, set, GEMSNode.SET);
1523 // Done
1524 set = null;
1525 setVisible(false);
1526
1527 }
1528 else{
1529 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Set_Already_Exists"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
1530 }
1531
1532 name_str = null;
1533 namespace_str = null;
1534 }//end do not inherit
1535 else {
1536 //Should change this to use XML parsing utilites --Matthew
1537 //lets grab the metadata we want to inherit from...
1538 String anitem = existingSetJComboBox.getSelectedItem().toString();
1539
1540 if(a_set_exists_with_this_namespace(namespace_field.getText()) == false){
1541 //setup to read the filename from mds file
1542 String [] items = anitem.split("#%");
1543 try {
1544 FileInputStream fstream = new FileInputStream(items[1].trim());
1545 BufferedReader in = new BufferedReader(new InputStreamReader(fstream, "UTF8"));
1546
1547 FileOutputStream out;
1548 PrintWriter p;
1549 //setup to write to filename from existing file
1550 try {
1551 out = new FileOutputStream(Utility.METADATA_DIR + File.separator+ namespace_str + ".mds");
1552 OutputStreamWriter pout = new OutputStreamWriter(out, "UTF8");
1553 p = new PrintWriter(pout);
1554
1555 while(in.ready()){
1556 String nextline = in.readLine();
1557
1558 if(nextline.matches(".+namespace=\".+\".*") == true) {
1559 nextline = nextline.replaceFirst("namespace=\".+\"","namespace=\"" + namespace_str+ "\"");
1560 }
1561 else {
1562 nextline = nextline.replaceFirst(">.+</Name>",">" + name_str + "</Name>");
1563 }
1564 p.print(nextline + "\n");
1565 }
1566 p.close();
1567
1568 MetadataSet loadedset = msm.loadMetadataSet(new File(Utility.METADATA_DIR + File.separator + namespace_str + ".mds"));
1569 model.add(null, loadedset, GEMSNode.SET);
1570 }
1571 catch(Exception e){
1572 System.out.println("Print file error");
1573 }
1574 }
1575 catch(Exception e){
1576 System.out.println("File Input error");
1577 }
1578
1579 }//msm.getset(namespacE) == null
1580 else{
1581 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Set_Already_Exists"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
1582 }
1583 setVisible(false);
1584 }
1585 } //if(source == ok_button)
1586 else if(source == cancel_button) {
1587 setVisible(false);
1588 }
1589 else {
1590 name_field.setText("");
1591 setVisible(true);
1592 }
1593 } //actionPerformed
1594
1595 public void dispose() {
1596 cancel_button = null;
1597 ok_button = null;
1598 name_field = null;
1599 super.dispose();
1600 }
1601 }
1602
1603 ////
1604 private class SetSelectionDialog
1605 extends ModalDialog
1606 implements ActionListener {
1607 private JButton cancel_button = null;
1608 private JButton ok_button = null;
1609 private JComboBox existingSetJComboBox = new JComboBox();
1610
1611 public SetSelectionDialog() {
1612 super(self);
1613 setModal(true);
1614 setSize(OPEN_SETS_SIZE);
1615 Dictionary.setText(this, "GEMS.Open_Set");
1616
1617 // Creation
1618 JPanel content_pane = (JPanel) getContentPane();
1619 content_pane.setBackground(config.getColor("coloring.collection_heading_background", false));
1620 JPanel center_pane = new JPanel();
1621 center_pane.setOpaque(false);
1622
1623 JPanel boxes_pane = new JPanel();
1624
1625 JPanel button_pane = new JPanel();
1626 button_pane.setOpaque(false);
1627
1628 ok_button = new GLIButton();
1629 ok_button.setMnemonic(KeyEvent.VK_O);
1630 getRootPane().setDefaultButton(ok_button);
1631 Dictionary.setBoth(ok_button, "General.OK", "General.OK_Tooltip");
1632 cancel_button = new GLIButton();
1633 cancel_button.setMnemonic(KeyEvent.VK_C);
1634 Dictionary.setBoth(cancel_button, "General.Cancel", "General.Pure_Cancel_Tooltip");
1635
1636 // Connection
1637 cancel_button.addActionListener(this);
1638 ok_button.addActionListener(this);
1639
1640 // Layout
1641 boxes_pane.setLayout(new GridLayout(4,1));
1642
1643 JLabel inheritJLabel = new JLabel();
1644 Dictionary.setText(inheritJLabel, "GEMS.inheritMetadataSet");
1645
1646 File[] col_dir = new File(Configuration.gsdl_path + File.separator + "collect").listFiles();
1647
1648 existingSetJComboBox.addItem("Default Metadata Sets #% " + Configuration.gsdl_path + "gli" + File.separator + "metadata");
1649
1650 for(int k = 0; k < col_dir.length; k++){
1651 if(col_dir[k].isDirectory() && col_dir[k].getName().compareTo("CVS") != 0) {
1652
1653 File metadir = new File(col_dir[k].toString() + File.separator + "metadata");
1654 if(metadir.exists())
1655 existingSetJComboBox.addItem(new String(col_dir[k].getName() + " Collection Sets #% " + col_dir[k].toString() + File.separator + "metadata"));
1656
1657 }
1658
1659 }
1660 //add sets to existingSetJComboBox
1661
1662 existingSetJComboBox.setSelectedIndex(0);
1663 JLabel dummyl = new JLabel();
1664 Dictionary.setText(dummyl, "GEMS.Add_Set.No_Inherit");
1665
1666 boxes_pane.add(new JLabel("Select which group of metadata sets you wish to edit:\n\n\n\n"));
1667 boxes_pane.add(new JLabel("\n"));
1668 boxes_pane.add(existingSetJComboBox);
1669 boxes_pane.add(new JLabel("\n"));
1670
1671 button_pane.setLayout(new GridLayout(1,3,0,5));
1672 button_pane.add(ok_button);
1673 button_pane.add(cancel_button);
1674
1675 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
1676 content_pane.setLayout(new BorderLayout());
1677 content_pane.add(boxes_pane, BorderLayout.CENTER);
1678 content_pane.add(button_pane, BorderLayout.SOUTH);
1679
1680 setLocation((config.screen_size.width - ADD_SET_SIZE.width) / 2, (config.screen_size.height - ADD_SET_SIZE.height) / 2);
1681 }
1682 /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
1683 * @param event An <strong>ActionEvent</strong> containing information about the event.
1684 */
1685
1686 public void actionPerformed(ActionEvent event) {
1687 Object source = event.getSource();
1688
1689 if(source == ok_button) {
1690 //this code below handles whether we inherit from an existing set or not
1691
1692 // String namespace_str = namespace_field.getText();
1693 //String name_str = Codec.transform(Codec.transformUnicode(name_field.getText()), Codec.TEXT_TO_DOM);
1694 String loc = (String) existingSetJComboBox.getSelectedItem();
1695
1696 String [] whereto = loc.split("#%");
1697 String set_directory = whereto[1].trim();
1698
1699 //load the jfilechooser:
1700
1701 JFileChooser metadata_set_file_chooser = new JFileChooser(new File(set_directory));
1702 metadata_set_file_chooser.setFileFilter(new MetadataSetFileFilter());
1703 if (metadata_set_file_chooser.showDialog(this, Dictionary.get("General.Open")) == JFileChooser.APPROVE_OPTION) {
1704 MetadataSet metadata_set = msm.loadMetadataSet(metadata_set_file_chooser.getSelectedFile());
1705 // Update tree
1706 //only update tree if the metadata_set return is not null(it will be null if set is already
1707 //opened-Attila - oct 19 0 4
1708 if(metadata_set != null) {
1709 model.add(null, metadata_set, GEMSNode.SET);
1710 }
1711 }
1712
1713
1714 setVisible(false);
1715 }
1716 else if(source == cancel_button) {
1717 setVisible(false);
1718 }
1719 else {
1720 setVisible(true);
1721 }
1722 }
1723
1724 public void dispose() {
1725 cancel_button = null;
1726 ok_button = null;
1727 super.dispose();
1728 }
1729 }
1730
1731 /*
1732 Class to handle removing set or element attributes.
1733 */
1734 private class RemoveAttributeActionListener
1735 implements ActionListener, KeyListener {
1736
1737 /**
1738 Any implementation of KeyListener must include these mothods.
1739 When the DELETE key is pressed, fire the actionPerformed event.
1740 @param e A <strong>KeyEvent</strong> containing information about the event.
1741 */
1742 public void keyTyped(KeyEvent e){
1743 //Do nothing
1744 }
1745 public void keyPressed(KeyEvent e)
1746 {
1747 if(e.getKeyCode() == java.awt.event.KeyEvent.VK_DELETE)
1748 {
1749 //DELETE key pressed
1750 actionPerformed((ActionEvent)null); //is there a better way?
1751 }
1752 }
1753 public void keyReleased(KeyEvent e) {
1754 //Do nothing
1755 }
1756
1757 /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
1758 * @param event An <strong>ActionEvent</strong> containing information about the event.
1759 */
1760 public void actionPerformed(ActionEvent event) {
1761 if(current_attribute != -1) {
1762 int result = JOptionPane.showOptionDialog(self, Dictionary.get("GEMS.Confirm_Removal", Dictionary.get("GEMS.Attribute")), Dictionary.get("GEMS.Confirm_Removal_Title"), JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dialog_options, dialog_options[0]);
1763 // Remove this attribute
1764 if(result == 0) {
1765 ignore = true;
1766 //Attributes are tricky little beasties, as they can come from several different places and depend upon what other little beasties have been selected
1767 //Has an element been selected
1768 if(current_element != null) {
1769 // Remove element attribute
1770 String name = (String) element_attributes.getValueAt(current_attribute, 0);
1771 String language = (String) element_attributes.getValueAt(current_attribute, 1);
1772 String value = (String) element_attributes.getValueAt(current_attribute, 2);
1773 current_element.removeAttribute(name, language, value);
1774
1775 // Refresh table
1776 ((AttributeTableModel)element_attributes.getModel()).removeRow(current_attribute);
1777 }
1778 else if(current_set != null) {
1779 String name = (String) set_attributes.getValueAt(current_attribute, 0);
1780 // Remove set attribute
1781 current_set.removeAttribute(name);
1782 // Refresh table
1783 ((AttributeTableModel)set_attributes.getModel()).removeRow(current_attribute);
1784 }
1785 ignore = false;
1786 atLeastOneSetChanged= true;
1787 }
1788 }
1789 else
1790 {
1791 System.err.println("Tried to remove attribute, but current_attribute == -1!!"); //This should not happen
1792 }
1793 }
1794 }
1795
1796 /*
1797 Class to handle deletion of elements (including subelements).
1798
1799 Last modified 2/02/05 by Matthew Whyte
1800 */
1801 private class RemoveElementActionListener
1802 implements ActionListener {
1803
1804 /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to provide an editing prompt.
1805 * @param event An <strong>ActionEvent</strong> containing information about the event.
1806 */
1807 public void actionPerformed(ActionEvent event) {
1808
1809 if(current_element != null) {
1810 int result = JOptionPane.showOptionDialog(self, Dictionary.get("GEMS.Confirm_Removal", Dictionary.get("GEMS.Element")), Dictionary.get("GEMS.Confirm_Removal_Title"), JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dialog_options, dialog_options[0]);
1811 // Remove this attribute
1812 if(result == 0) {
1813 //Get the parent element
1814 GEMSNode parent_node = (GEMSNode)current_node.getParent();
1815 ElementWrapper parent_wrapped = parent_node.getElement();
1816
1817 ignore = true;
1818 msm.removeElement(current_element, parent_wrapped);
1819 // Clear selection
1820 mds_tree.clearSelection();
1821 model.remove(current_node);
1822
1823 // Show a blank panel.
1824 card_layout.show(details_pane, BLANK);
1825 ignore = false;
1826
1827 atLeastOneSetChanged = true;
1828 }
1829 }
1830 else {
1831 System.err.println("No element currently selected."); //This should not happen!
1832 }
1833 }
1834 }
1835
1836
1837 /**
1838 Class to handle renaming of a set and/or it's namespace.
1839
1840 @author: Matthew Whyte
1841 Date last modified: 10/01/05
1842 */
1843 private class RenameSetActionListener extends ModalDialog implements ActionListener {
1844
1845 private JButton cancel_button = null;
1846 private JButton ok_button = null;
1847 private JTextField name_field = null;
1848 private JTextField namespace_field = null;
1849
1850 public RenameSetActionListener() {
1851 super(self);
1852 setModal(true);
1853 setSize(RENAME_SET_SIZE);
1854 Dictionary.setText(this, "GEMS.Rename_Set");
1855
1856 // Creation
1857 JPanel content_pane = (JPanel) getContentPane();
1858 content_pane.setBackground(config.getColor("coloring.collection_heading_background", false));
1859 JPanel center_pane = new JPanel();
1860 center_pane.setOpaque(false);
1861
1862 JPanel label_pane = new JPanel();
1863 JPanel boxes_pane = new JPanel();
1864
1865 JLabel namespace_label = new JLabel();
1866 namespace_label.setOpaque(false);
1867 Dictionary.setText(namespace_label, "GEMS.Namespace");
1868 namespace_field = TransformCharacterTextField.createNamespaceTextField();
1869 namespace_field.setBackground(config.getColor("coloring.collection_tree_background", false));
1870 namespace_field.setForeground(config.getColor("coloring.collection_tree_foreground", false));
1871 namespace_field.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
1872 namespace_field.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
1873 Dictionary.setTooltip(namespace_field, "GEMS.Rename_Namespace_Tooltip");
1874
1875 JLabel name_label = new JLabel();
1876 name_label.setOpaque(false);
1877 Dictionary.setText(name_label, "GEMS.Name");
1878 name_field = new JTextField();
1879 name_field.setBackground(config.getColor("coloring.collection_tree_background", false));
1880 name_field.setForeground(config.getColor("coloring.collection_tree_foreground", false));
1881 name_field.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
1882 name_field.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
1883 Dictionary.setTooltip(name_field, "GEMS.Rename_Name_Tooltip");
1884
1885 JPanel button_pane = new JPanel();
1886 button_pane.setOpaque(false);
1887
1888 ok_button = new GLIButton();
1889 ok_button.setMnemonic(KeyEvent.VK_O);
1890 getRootPane().setDefaultButton(ok_button);
1891 Dictionary.setBoth(ok_button, "General.OK", "General.OK_Tooltip");
1892 cancel_button = new GLIButton();
1893 cancel_button.setMnemonic(KeyEvent.VK_C);
1894 Dictionary.setBoth(cancel_button, "General.Cancel", "General.Pure_Cancel_Tooltip");
1895 TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
1896
1897 // Connection
1898 cancel_button.addActionListener(this);
1899 ok_button.addActionListener(this);
1900 ok_button_enabler.add(name_field);
1901 ok_button_enabler.add(namespace_field);
1902
1903 // Layout
1904 label_pane.setLayout(new GridLayout(2,1));
1905 label_pane.add(name_label);
1906 label_pane.add(namespace_label);
1907 boxes_pane.setLayout(new GridLayout(2,1));
1908 boxes_pane.add(name_field);
1909 boxes_pane.add(namespace_field);
1910
1911 center_pane.setLayout(new BorderLayout(5,0));
1912 center_pane.add(label_pane, BorderLayout.WEST);
1913 center_pane.add(boxes_pane, BorderLayout.CENTER);
1914
1915 button_pane.setLayout(new GridLayout(1,2,0,5));
1916 button_pane.add(ok_button);
1917 button_pane.add(cancel_button);
1918
1919 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
1920 content_pane.setLayout(new BorderLayout());
1921 content_pane.add(center_pane, BorderLayout.CENTER);
1922 content_pane.add(button_pane, BorderLayout.SOUTH);
1923
1924 setLocation((config.screen_size.width - RENAME_SET_SIZE.width) / 2, (config.screen_size.height - RENAME_SET_SIZE.height) / 2);
1925 }
1926
1927 private boolean a_set_exists_with_this_namespace(String namespace){
1928 Vector p = msm.getSets();
1929 boolean flag = false;
1930 for(int k = 0; k < p.size(); k++){
1931 MetadataSet s = (MetadataSet)p.get(k);
1932
1933 if(s.getNamespace().compareTo(namespace) == 0){
1934 flag = true;
1935 }
1936 }
1937 return flag;
1938 }
1939
1940
1941 /**
1942 Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component,
1943 allowing us to
1944 * @param event An <strong>ActionEvent</strong> containing information about the event.
1945 */
1946 public void actionPerformed(ActionEvent event) {
1947 Object source = event.getSource();
1948
1949 if(source == ok_button)
1950 {
1951 String namespace_str = namespace_field.getText();
1952 String name_str = Codec.transform(Codec.transformUnicode(name_field.getText()), Codec.TEXT_TO_DOM);
1953 //Note: The name in name_str is language dependent. However, currently GEMS does not create new sets with different names for different languages(?).
1954 String current_set_namespace = current_set.getNamespace();
1955
1956 //Ensure that the namespace is unique.
1957 if(!(a_set_exists_with_this_namespace(namespace_str)) || (namespace_str.equals(current_set_namespace)))
1958 {
1959 //Hide the set that are about to rename
1960 mds_tree.clearSelection();
1961 model.remove(current_node);
1962
1963 //Rename set & namespace
1964 msm.renameSet(current_set, namespace_str, name_str);
1965 //Add (renamed) set back to tree
1966 model.add(null, current_set, GEMSNode.SET);
1967
1968 //Clean up
1969 card_layout.show(details_pane, BLANK); // Show a blank panel.
1970 ignore = false;
1971 atLeastOneSetChanged = true;
1972 setVisible(false);
1973 }
1974
1975 // Otherwise show an error message and do not proceed.
1976 else
1977 {
1978 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Set_Already_Exists"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
1979 }
1980 name_str = null;
1981
1982 }
1983
1984 else if(source == cancel_button)
1985 {
1986 setVisible(false); //hide dialog
1987 }
1988 else
1989 {
1990 name_field.setText(current_set.getName());
1991 namespace_field.setText(current_set.getNamespace());
1992 setVisible(true); //Show the dialog
1993 }
1994 source = null;
1995 }
1996
1997 public void dispose() {
1998 cancel_button = null;
1999 ok_button = null;
2000 name_field = null;
2001 super.dispose();
2002 }
2003 }
2004
2005
2006
2007 /**
2008 Class to handle renaming of an element.
2009
2010 @author: Matthew Whyte
2011 Date last modified: 10/01/05
2012 */
2013 private class RenameElementActionListener extends ModalDialog implements ActionListener {
2014
2015 protected JButton cancel_button = null;
2016 protected JButton ok_button = null;
2017 //private JLabel label = null;
2018 protected NonWhitespaceField name_field = null;
2019
2020 public RenameElementActionListener() {
2021 super(self);
2022 setModal(true);
2023 setSize(RENAME_ELEMENT_SIZE);
2024 // Creation
2025 JPanel content_pane = (JPanel) getContentPane();
2026 content_pane.setBackground(config.getColor("coloring.collection_heading_background", false));
2027 JPanel center_pane = new JPanel();
2028 center_pane.setOpaque(false);
2029
2030 JPanel labels_pane = new JPanel();
2031 labels_pane.setOpaque(false);
2032
2033 JPanel values_pane = new JPanel();
2034 values_pane.setOpaque(false);
2035 JLabel name_label = new JLabel();
2036 name_label.setOpaque(false);
2037 Dictionary.setText(name_label, "GEMS.New_Name");
2038 name_field = new NonWhitespaceField();
2039 name_field.setBackground(config.getColor("coloring.collection_tree_background", false));
2040 name_field.setForeground(config.getColor("coloring.collection_tree_foreground", false));
2041 name_field.setSelectionColor(config.getColor("coloring.collection_selection_background", false));
2042 name_field.setSelectedTextColor(config.getColor("coloring.collection_selection_foreground", false));
2043 Dictionary.setTooltip(name_field, "GEMS.Rename_Element_Tooltip");
2044
2045 JPanel button_pane = new JPanel();
2046 button_pane.setOpaque(false);
2047
2048 ok_button = new GLIButton();
2049 ok_button.setMnemonic(KeyEvent.VK_O);
2050 getRootPane().setDefaultButton(ok_button);
2051 Dictionary.setBoth(ok_button, "General.OK", "General.OK_Tooltip");
2052 cancel_button = new GLIButton();
2053 cancel_button.setMnemonic(KeyEvent.VK_C);
2054 Dictionary.setBoth(cancel_button, "General.Cancel", "General.Pure_Cancel_Tooltip");
2055
2056 TextFieldEnabler ok_button_enabler = new TextFieldEnabler(ok_button);
2057
2058 Dictionary.setText(this, "GEMS.Rename_Element");
2059
2060 // Connection
2061 cancel_button.addActionListener(this);
2062 ok_button.addActionListener(this);
2063 ok_button_enabler.add(name_field);
2064
2065 // Layout
2066 labels_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
2067 labels_pane.setLayout(new GridLayout(1,1));
2068 //labels_pane.add(set_label);
2069 labels_pane.add(name_label);
2070
2071 values_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
2072 values_pane.setLayout(new GridLayout(1,1));
2073 //values_pane.add(label);
2074 values_pane.add(name_field);
2075
2076 center_pane.setLayout(new BorderLayout(5,5));
2077 center_pane.add(labels_pane, BorderLayout.WEST);
2078 center_pane.add(values_pane, BorderLayout.CENTER);
2079
2080 button_pane.setLayout(new GridLayout(1,2,0,5));
2081 button_pane.add(ok_button);
2082 button_pane.add(cancel_button);
2083
2084 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
2085 content_pane.setLayout(new BorderLayout());
2086 content_pane.add(center_pane, BorderLayout.CENTER);
2087 content_pane.add(button_pane, BorderLayout.SOUTH);
2088
2089 setLocation((config.screen_size.width - ADD_ELEMENT_SIZE.width) / 2, (config.screen_size.height - ADD_ELEMENT_SIZE.height) / 2);
2090 }
2091
2092
2093 /**
2094 Any implementation of ActionListener must include this method so that we can be informed when an action has occured.
2095 @param event An <string>ActionEvent</strong> containing information about the event.
2096 */
2097 public void actionPerformed(ActionEvent event)
2098 {
2099 Object source = event.getSource();
2100
2101 if(source == ok_button)
2102 {
2103 TreeNode selPath = current_node.getParent();
2104 GEMSNode parent = (GEMSNode)selPath;
2105 MetadataSet currentSet = msm.getSet(current_element.getNamespace());
2106 String name_str = Codec.transform(Codec.transformUnicode(name_field.getText()), Codec.TEXT_TO_DOM);
2107 GEMSNode new_node = null;
2108
2109 // If this element doesn't already exist.
2110 if(!currentSet.containsElement(name_str)) //Do the renaming!
2111 {
2112 model.remove(current_node); //Hide the element that are about to rename
2113 msm.renameElement(current_element, name_str); //rename the element
2114 //Add the new element
2115 new_node = model.add(parent, current_element, GEMSNode.ELEMENT);
2116
2117 //mds_tree.setSelectionPath(new_node_path); //would like to do this but doesn't hilight tree :-(
2118 card_layout.show(details_pane, BLANK); // Show a blank panel.
2119
2120 //finish up
2121 currentSet.setSetChanged(true);
2122 atLeastOneSetChanged = true;
2123 setVisible(false);
2124 }
2125
2126 // Otherwise show an error message and do not proceed.
2127 else
2128 {
2129 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Element_Already_Exists"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
2130 }
2131 name_str = null;
2132
2133 }
2134
2135 else if(source == cancel_button)
2136 {
2137 setVisible(false); //hide dialog
2138 }
2139 else
2140 {
2141 name_field.setText(current_element.getNameOnly()); //show old name (without namespace)
2142 setVisible(true); //Show the dialog
2143 }
2144
2145 source = null;
2146 }
2147
2148 public void dispose() {
2149 cancel_button = null;
2150 ok_button = null;
2151 name_field = null;
2152 super.dispose();
2153 }
2154 }
2155
2156
2157 /**
2158 Class to handle DELETE key presses on the tree.
2159 The class then fires the appropriate event to remove that element/set.
2160 Attributes in the table are handled directly by the RemoveAttributeActionListener
2161
2162 Author: Matthew Whyte
2163 Date last modified: 25/01/05
2164 */
2165 private class KeyPressedHandler implements KeyListener, ActionListener {
2166
2167 // All implementations of KeyListener requires these methods
2168 public void keyTyped(KeyEvent e){
2169 //Do nothing
2170 }
2171 public void keyPressed(KeyEvent e)
2172 {
2173
2174 if(e.getKeyCode() == java.awt.event.KeyEvent.VK_DELETE) //DELETE key pressed
2175 {
2176 this.removeItem();
2177 }
2178 }
2179 public void keyReleased(KeyEvent e)
2180 {
2181 //Do nothing
2182 }
2183
2184 public void actionPerformed(ActionEvent event)
2185 {
2186 this.removeItem();
2187 }
2188
2189 public void removeItem()
2190 {
2191 boolean cont = true;
2192
2193 /**
2194 Check to see if more than one tree node/leaf is selected. If so don't continue.
2195
2196 This could be updated to delete multiple nodes/leaves in the futere.
2197 But not me and not today!!
2198 */
2199 TreePath[] multiSelectionCheck = mds_tree.getSelectionPaths();
2200 if(multiSelectionCheck.length > 1)
2201 {
2202 cont = false;
2203 Toolkit.getDefaultToolkit().beep();
2204 }
2205
2206 if(cont)
2207 {
2208 //Check to see if pressed on Set or Element.
2209 TreePath selPath = mds_tree.getSelectionPath();
2210 GEMSNode t = (GEMSNode)selPath.getLastPathComponent();
2211
2212 if(t.type == T_ELEMENT) //Remove the element
2213 {
2214 RemoveElementActionListener removeElement = new RemoveElementActionListener();
2215 removeElement.actionPerformed((ActionEvent)null);
2216 }
2217 else if(t.type == T_SET) //Remove the whole set
2218 {
2219 RemoveSetActionListener removeSet = new RemoveSetActionListener();
2220 removeSet.actionPerformed((ActionEvent)null);
2221 }
2222 }
2223 }
2224 }
2225
2226
2227 private class RemoveSetActionListener
2228 implements ActionListener {
2229
2230 /** Any implementation of ActionListener must include this method so that we can be informed when an action as occured on our registered component, allowing us to
2231 * @param event An <strong>ActionEvent</strong> containing information about the event.
2232 */
2233 public void actionPerformed(ActionEvent event) {
2234 if(current_set != null) {
2235
2236 //If the current_set_filename is dls or dublin or ex and in the METADATA_DIR, then do
2237 //not let anyone remove them --Attila
2238 File current_set_filename = current_set.getFile();
2239 if(current_set_filename.toString().compareTo(new String(Utility.METADATA_DIR+"dls.mds")) == 0 ||
2240 current_set_filename.toString().compareTo(new String(Utility.METADATA_DIR+"dublin.mds")) == 0 ||
2241 current_set_filename.toString().compareTo(new String(Utility.METADATA_DIR+"ex.mds")) == 0){
2242
2243 JOptionPane.showMessageDialog(self, Dictionary.get("GEMS.Cannot_Delete_Core_Sets_Error"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
2244 return;
2245 }
2246
2247
2248 int result = JOptionPane.showOptionDialog(self, Dictionary.get("GEMS.Confirm_Removal", Dictionary.get("GEMS.Set") + " " + Dictionary.get("GEMS.Cannot_Undo")), Dictionary.get("GEMS.Confirm_Removal_Title"), JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dialog_options, dialog_options[0]);
2249 // Remove the currently selected set
2250 if(result == 0) {
2251
2252 ignore = true;
2253 msm.removeSet(current_set);
2254 // Clear selection
2255 mds_tree.clearSelection();
2256 model.remove(current_node);
2257 card_layout.show(details_pane, BLANK); //Show a blank panel.
2258 ignore = false;
2259
2260 }
2261 }
2262 }
2263 }
2264
2265 /** Used to enable a certain target component if and only if all the registered text fields contain non-zero length strings. */
2266 private class TextFieldEnabler
2267 implements DocumentListener {
2268 private boolean ignore = false;
2269 private Component target = null;
2270 private JTextComponent[] fields = null;
2271 public TextFieldEnabler(Component target) {
2272 super();
2273 this.target = target;
2274 }
2275 public void add(JTextComponent field) {
2276 // Record this field as being one we depend upon
2277 if(fields == null) {
2278 fields = new JTextComponent[1];
2279 fields[0] = field;
2280 }
2281 else {
2282 JTextComponent[] temp = new JTextComponent[fields.length + 1];
2283 System.arraycopy(fields, 0, temp, 0, fields.length);
2284 temp[fields.length] = field;
2285 fields = temp;
2286 temp = null;
2287 }
2288 // Add the appropriate listener
2289 field.getDocument().addDocumentListener(this);
2290 }
2291 /** Gives notification that an attribute or set of attributes changed. */
2292 public void changedUpdate(DocumentEvent e) {
2293 canEnable();
2294 }
2295 /** Gives notification that there was an insert into the document. */
2296 public void insertUpdate(DocumentEvent e) {
2297 canEnable();
2298 }
2299 /** Gives notification that a portion of the document has been removed. */
2300 public void removeUpdate(DocumentEvent e) {
2301 canEnable();
2302 }
2303 private void canEnable() {
2304 if(!ignore) {
2305 ignore = true;
2306 boolean can_enable = true;
2307 for(int i = 0; can_enable && i < fields.length; i++) {
2308 can_enable = can_enable && (fields[i].getText().length() > 0);
2309 }
2310 target.setEnabled(can_enable);
2311 ignore = false;
2312 }
2313 }
2314 }
2315
2316 private class AttributesListSelectionListener
2317 implements ListSelectionListener
2318 {
2319 private JTable table = null;
2320 public AttributesListSelectionListener(JTable table)
2321 {
2322 this.table = table;
2323 }
2324
2325 public void valueChanged(ListSelectionEvent event)
2326 {
2327 if(!event.getValueIsAdjusting())
2328 {
2329 current_attribute = table.getSelectedRow();
2330 }
2331 }
2332 }
2333
2334 private class MDSTreeSelectionListener
2335 implements TreeSelectionListener {
2336 public void valueChanged(TreeSelectionEvent event) {
2337 if(!ignore) {
2338 // Clear all variables based on previous tree selection
2339 current_element = null;
2340 current_set = null;
2341 // Now process the node selected
2342 TreePath path = event.getPath();
2343 current_node = (GEMSNode)path.getLastPathComponent();
2344 // What we show depends on the node type...
2345 AttributeTableModel atm = null;
2346 TreeSet attributes = null;
2347 current_attribute_type = current_node.getType();
2348 switch(current_attribute_type) {
2349
2350 case GEMSNode.ELEMENT:
2351 current_element = current_node.getElement();
2352 atm = current_node.getModel();
2353 if(atm == null) {
2354 atm = new AttributeTableModel(current_element.getAttributes(), Dictionary.get("GEMS.Name"), Dictionary.get("GEMS.Language_Code"), Dictionary.get("GEMS.Value"), "");
2355 //current_node.setModel(atm);
2356 }
2357 element_attributes.setModel(atm);
2358 atm.setScrollPane(element_attributes_scroll);
2359 atm.setTable(element_attributes);
2360
2361 card_layout.show(details_pane, ELEMENT);
2362 break;
2363 case GEMSNode.SET:
2364 current_set = current_node.getSet();
2365 atm = current_node.getModel();
2366 if(atm == null) {
2367 NamedNodeMap temp = current_set.getAttributes();
2368 attributes = new TreeSet();
2369 for(int i = 0; i < temp.getLength(); i++) {
2370 Attr attribute = (Attr) temp.item(i);
2371 // We don't show the namespace attribute, as it is used as a unique primary key and should never be changed or removed in itself.
2372 if(!attribute.getName().equals("namespace")) {
2373 attributes.add(new Attribute(attribute.getName(), attribute.getValue()));
2374 }
2375 attribute = null;
2376 }
2377 atm = new AttributeTableModel(attributes, Dictionary.get("GEMS.Name"), Dictionary.get("GEMS.Value"), "");
2378 temp = null;
2379 }
2380 set_attributes.setModel(atm);
2381 atm.setScrollPane(set_attributes_scroll);
2382 atm.setTable(set_attributes);
2383
2384 card_layout.show(details_pane, SET);
2385 attributes = null;
2386 break;
2387
2388 default:
2389 // Show a blank panel.
2390 card_layout.show(details_pane, BLANK);
2391 }
2392 attributes = null;
2393 path = null;
2394 atm = null;
2395 }
2396 }
2397 }
2398
2399 private class GEMSTreeCellRenderer
2400 extends DefaultTreeCellRenderer {
2401 public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
2402 super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
2403 setToolTipText(value.toString());
2404 return this;
2405 }
2406 }
2407
2408
2409 //PopupListener is our main manager for all right-click popups
2410 class PopupListener extends MouseAdapter implements ActionListener{
2411 JPopupMenu setPopup;
2412 JPopupMenu elementPopup;
2413 JPopupMenu attributePopup;
2414
2415 //all of our popup menu items EVER!
2416 JMenuItem menuAddAttributeSet;
2417 JMenuItem menuAddElement;
2418 JMenuItem menuRenameSet;
2419 JMenuItem menuRemoveSet;
2420
2421 JMenuItem menuAddAttributeElement;
2422 JMenuItem menuAddSubelement;
2423 JMenuItem menuRenameElement;
2424 JMenuItem menuDeleteElement;
2425
2426 JMenuItem menuAddAttributeAttribute;
2427 JMenuItem menuEditValue;
2428 JMenuItem menuDeleteAttribute;
2429
2430 GEMS GEMSRef = null;
2431 PopupListener(GEMS g) {
2432 setPopup = new JPopupMenu();
2433 elementPopup = new JPopupMenu();
2434 attributePopup = new JPopupMenu();
2435
2436 //reference to our parent(GEMS), because some of the actionlisteners would not
2437 //work unless they were declared in GEMS, and I need a way to reference GEMS
2438 GEMSRef = g;
2439
2440 //Create the menu items
2441 menuAddAttributeSet = new JMenuItem();
2442 Dictionary.setBoth(menuAddAttributeSet, "GEMS.Add_Attribute", "GEMS.Add_Attribute_Tooltip");
2443 menuAddElement =new JMenuItem();
2444 Dictionary.setBoth(menuAddElement,"GEMS.Add_Element","GEMS.Add_Element_Tooltip");
2445 menuRenameSet = new JMenuItem();
2446 Dictionary.setBoth(menuRenameSet,"GEMS.Rename_Set", "GEMS.Rename_Set_Tooltip");
2447 menuRemoveSet = new JMenuItem();
2448 Dictionary.setBoth(menuRemoveSet, "GEMS.Remove_Set","GEMS.Remove_Set_Tooltip");
2449
2450 menuAddAttributeElement=new JMenuItem();
2451 Dictionary.setBoth(menuAddAttributeElement,"GEMS.Add_Attribute", "GEMS.Add_Attribute_Tooltip");
2452 menuAddSubelement=new JMenuItem();
2453 Dictionary.setBoth(menuAddSubelement,"GEMS.Add_Subelement", "GEMS.Add_Subelement_Tooltip");
2454 menuRenameElement=new JMenuItem();
2455 Dictionary.setBoth(menuRenameElement,"GEMS.Rename_Element", "GEMS.Rename_Element_Tooltip");
2456 menuDeleteElement=new JMenuItem();
2457 Dictionary.setBoth(menuDeleteElement,"GEMS.Remove_Element", "GEMS.Remove_Element_Tooltip" );
2458
2459 menuAddAttributeAttribute=new JMenuItem();
2460 Dictionary.setBoth(menuAddAttributeAttribute,"GEMS.Add_Attribute", "GEMS.Add_Attribute_Tooltip");
2461 menuEditValue=new JMenuItem();
2462 Dictionary.setBoth(menuEditValue,"GEMS.Edit_Value", "GEMS.Edit_Value_Tooltip");
2463 menuDeleteAttribute=new JMenuItem();
2464 Dictionary.setBoth(menuDeleteAttribute,"GEMS.Remove_Attribute", "GEMS.Remove_Attribute_Tooltip");
2465
2466 //Associate the menu items with the appropriate popups:
2467 setPopup.add(menuAddAttributeSet);
2468 setPopup.add(menuAddElement);
2469 setPopup.add(menuRenameSet);
2470 setPopup.add(menuRemoveSet);
2471
2472 elementPopup.add(menuAddAttributeElement);
2473 elementPopup.add(menuAddSubelement);
2474 elementPopup.add(menuRenameElement);
2475 elementPopup.add(menuDeleteElement);
2476
2477 attributePopup.add(menuAddAttributeAttribute);
2478 attributePopup.add(menuEditValue);
2479 attributePopup.add(menuDeleteAttribute);
2480
2481 //Add appropriate action listeners to the menu items.
2482 menuAddAttributeSet.addActionListener(new AddOrEditAttributeActionListener());
2483 menuAddElement.addActionListener(new AddElementActionListener());
2484 menuRenameSet.addActionListener(new RenameSetActionListener());
2485 menuRemoveSet.addActionListener(new RemoveSetActionListener());
2486
2487 menuAddAttributeElement.addActionListener(new AddOrEditAttributeActionListener());
2488 menuAddSubelement.addActionListener(new AddSubelementActionListener());
2489 menuRenameElement.addActionListener(new RenameElementActionListener());
2490 menuDeleteElement.addActionListener(new RemoveElementActionListener());
2491
2492 menuEditValue.addActionListener(new AddOrEditAttributeActionListener());
2493 menuDeleteAttribute.addActionListener(new RemoveAttributeActionListener());
2494 menuAddAttributeAttribute.addActionListener(new AddOrEditAttributeActionListener());
2495 }
2496
2497 public void mouseClicked(MouseEvent e) {
2498 maybeShowPopup(e);
2499 }
2500 public void mousePressed(MouseEvent e){
2501 maybeShowPopup(e);
2502 }
2503 public void mouseReleased(MouseEvent e) {
2504 maybeShowPopup(e);
2505 }
2506
2507 private void maybeShowPopup(MouseEvent e) {
2508 TreePath selPath = mds_tree.getPathForLocation(e.getX(), e.getY());
2509 Point p = null;
2510 if (e.isPopupTrigger()) {
2511
2512 if(e.getSource() == mds_tree) {
2513 try {
2514 GEMSNode t = (GEMSNode)selPath.getLastPathComponent();
2515
2516 mds_tree.setSelectionPath(selPath); //Select node right-clicked on
2517
2518 if(t.type == T_ELEMENT){
2519 elementPopup.show(e.getComponent(), e.getX(), e.getY());
2520 }
2521 else if(t.type == T_SET){
2522 setPopup.show(e.getComponent(), e.getX(), e.getY());
2523 }
2524 }
2525 catch(Exception NullPointerException) {
2526 //Right-clicked in tree area, but no item to select. Do nothing.
2527 }
2528 }
2529 else if(e.getSource() == set_attributes){ //When right-click on table of set attributes
2530 //Select the table row that was right-clicked on.
2531 p = e.getPoint();
2532 set_attributes.changeSelection(set_attributes.rowAtPoint(p), set_attributes.columnAtPoint(p), false, false);
2533 attributePopup.show(e.getComponent(), e.getX(), e.getY());
2534 }
2535 else if(e.getSource() == element_attributes) { //When right-click on table of element attributes
2536 //Select the table row that was right-clicked on.
2537 p = e.getPoint();
2538 element_attributes.changeSelection(element_attributes.rowAtPoint(p), element_attributes.columnAtPoint(p), false, false);
2539 attributePopup.show(e.getComponent(), e.getX(), e.getY());
2540 }
2541 }
2542 }
2543
2544 public void actionPerformed(ActionEvent e) {
2545 //This should never happen!!
2546 System.err.println("Error: actionPerformed was called in class PopupListener. This should never happen!");
2547 }
2548 }
2549
2550 /** Wrap a ElementWrapper so we get its name when we ask for toString(), not its identifier. */
2551 private class NameElementWrapperEntry
2552 implements Comparable {
2553 private ElementWrapper element_wrapper = null;
2554 public NameElementWrapperEntry(Object object) {
2555 this.element_wrapper = (ElementWrapper) object;
2556 }
2557 public int compareTo(Object object) {
2558 return element_wrapper.compareTo(object);
2559 }
2560 public boolean equals(Object object) {
2561 return element_wrapper.equals(object);
2562 }
2563 public String toString() {
2564 return element_wrapper.getName();
2565 }
2566 }
2567}
Note: See TracBrowser for help on using the repository browser.