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

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

More GEMS fixes, by Matthew Whyte. Can now create subelements of subelements.

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