source: trunk/gli/src/org/greenstone/gatherer/msm/MSMPrompt.java@ 5777

Last change on this file since 5777 was 5777, checked in by mdewsnip, 21 years ago

Fixed bug 169: metadata element names and identifiers being confused when importing metadata (in collect view). Names and identifiers are still opposite to the way I would have them, but at least the bug is fixed.

  • Property svn:keywords set to Author Date Id Revision
File size: 41.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 the
6 * University of Waikato, New Zealand.
7 *
8 * <BR><BR>
9 *
10 * Author: John Thompson, Greenstone Digital Library, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 1999 New Zealand Digital Library Project
15 *
16 * <BR><BR>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * <BR><BR>
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * <BR><BR>
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 *########################################################################
36 */
37package org.greenstone.gatherer.msm;
38
39import java.awt.*;
40import java.awt.event.*;
41import java.io.*;
42import java.util.*;
43import javax.swing.*;
44import javax.swing.event.*;
45import org.greenstone.gatherer.Dictionary;
46import org.greenstone.gatherer.Gatherer;
47import org.greenstone.gatherer.gui.ModalDialog;
48import org.greenstone.gatherer.gui.SimpleMenuBar;
49import org.greenstone.gatherer.msm.Declarations;
50import org.greenstone.gatherer.msm.MetadataSet;
51import org.greenstone.gatherer.msm.MetadataSetManager;
52import org.greenstone.gatherer.msm.MSMUtils;
53import org.greenstone.gatherer.util.ArrayTools;
54import org.w3c.dom.*;
55
56/** A class dedicated to producing the visual components used by the MSM package.
57 * @author John Thompson, Greenstone Digital Library, University of Waikato
58 * @version 1.2
59 */
60public class MSMPrompt
61 implements ActionListener {
62
63 private boolean dialog_cancelled = false;
64 private Dimension screen_size = null;
65 private int action = Declarations.NO_ACTION;
66 private JButton add = null;
67 private JButton cancel = null;
68 private JButton merge = null;
69 private JButton rename = null;
70 private JButton replace = null;
71 private JButton skip = null;
72 private JDialog on_screen = null;
73 private JDialog dialog = null;
74 private JProgressBar progress = null;
75 private MetadataSetManager manager = null;
76 private Object result = null;
77
78 final static private Dimension MDE_SIZE = new Dimension(500,250);
79 final static private Dimension MDS_SIZE = new Dimension(800,425);
80 final static private Dimension PROGRESS_SIZE = new Dimension(500,105);
81 final static private Dimension RENAME_LABEL_SIZE = new Dimension(100,25);
82 final static private Dimension RENAME_SIZE = new Dimension(300,145);
83 final static private Dimension SELECT_ELEMENT_SIZE = new Dimension(500,305);
84 final static private Dimension SELECT_LABEL_SIZE = new Dimension(175, 25);
85 final static private Dimension SELECT_SET_SIZE = new Dimension(600,210);
86 final static private Dimension SELECT_SIZE = new Dimension(200,225);
87 final static private int SELECT_LINE_COUNT = 8;
88
89 public MSMPrompt(MetadataSetManager manager) {
90 this.manager = manager;
91
92 // Create components
93 cancel = new JButton();
94 cancel.addActionListener(this);
95 cancel.setEnabled(true);
96 cancel.setMnemonic(KeyEvent.VK_C);
97 Dictionary.registerBoth(cancel, "General.Cancel", "General.Cancel_Tooltip");
98
99 progress = new JProgressBar();
100 progress.setStringPainted(true);
101
102 screen_size = Gatherer.config.screen_size;
103 }
104
105 /** When called this method produces a nice error message on the screen, advising the user that the add action has failed.
106 * @param mde_new The <strong>Element</strong> that we were attempting to add.
107 * @param reason The phrase key for the reason the add failed, as a <strong>String</strong>.
108 */
109 public void addFailed(Element mde_new, String reason) {
110 String args[] = new String[2];
111 args[0] = mde_new.getAttribute("name");
112 args[1] = Dictionary.get(reason);
113 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("MSMPrompt.Add_Failed", args), Dictionary.get("MSMPrompt.Add_Failed_Title"), JOptionPane.ERROR_MESSAGE);
114 }
115
116 /** Any implementation of <i>ActionListener</i> must include this method so that we can be informed when an action has occured.
117 * @param event An <strong>ActionEvent</strong> containing information gatherer when this event occured.
118 */
119 public void actionPerformed(ActionEvent event) {
120 Object source = event.getSource();
121 action = Declarations.NO_ACTION;
122 if (add != null && source == add) {
123 action = Declarations.ADD;
124 }
125 else if (cancel != null && source == cancel) {
126 action = Declarations.CANCEL;
127 }
128 else if (merge != null && source == merge) {
129 action = Declarations.MERGE;
130 }
131 else if (rename != null && source == rename) {
132 action = Declarations.RENAME;
133 }
134 else if (replace != null && source == replace) {
135 action = Declarations.REPLACE;
136 }
137 else if (skip != null && source == skip) {
138 action = Declarations.SKIP;
139 }
140 on_screen.setVisible(false);
141 }
142
143 /** Method called when the merging process is complete and the progress bar is no longer needed.
144 */
145 public void endMerge() {
146 }
147
148 /** Method to indicate that yet another element has been succesfully merged, so that progress bar should reflect this.
149 */
150 public void incrementMerge() {
151 progress.setValue(progress.getValue() + 1);
152 String percent = ((100 * progress.getValue()) / progress.getMaximum()) + "%";
153 progress.setString(percent);
154 }
155
156 /** Method to display the metadata element merging prompt, wherein the user determines how the attributes within an element should be merged.
157 * @param mde_cur The current <strong>Element</strong> we are merging against.
158 * @param atts_cur The list of matching attribute <strong>Elements</strong> of the current element in question.
159 * @param mde_new The <strong>Element</strong> which we have choosen to merge in, and whose attributes are being examined.
160 * @param att_new And the new elements attribute <strong>Element</strong>.
161 * @return An object, which is either an Integer specifying what further action should be undertaken, if any, or if the action was replace, returns an Element, which is the attribute Element to replace with the new one
162 */
163 public Object mDEPrompt(Element mde_cur, Element[] atts_cur, Element mde_new, Element att_new) {
164 action = Declarations.NO_ACTION;
165
166 // Construction and configuration
167 JDialog dialog = new ModalDialog(Gatherer.g_man);
168 dialog.setModal(true);
169 dialog.setSize(MDE_SIZE);
170 dialog.setJMenuBar(new SimpleMenuBar("importingpreviouslyassignedmetadata"));
171 Dictionary.setText(dialog, "MSMPrompt.Merge_MDE");
172
173 JPanel content_pane = (JPanel)dialog.getContentPane();
174
175 JLabel element_name_label = new JLabel();
176 Dictionary.setText(element_name_label, "MSMPrompt.Element_Name");
177 JLabel element_name = new JLabel(MSMUtils.getFullName(mde_cur));
178
179 JLabel attribute_name_label = new JLabel();
180 Dictionary.setText(attribute_name_label, "MSMPrompt.Attribute");
181 JLabel attribute_name = new JLabel(att_new.getAttribute("name"));
182
183 add = new JButton();
184 add.addActionListener(this);
185 add.setEnabled(true);
186 add.setMnemonic(KeyEvent.VK_A);
187 Dictionary.registerBoth(add, "MSMPrompt.Add", "MSMPrompt.Add_Tooltip");
188
189 replace = new JButton();
190 replace.addActionListener(this);
191 replace.setEnabled(false);
192 replace.setMnemonic(KeyEvent.VK_R);
193 Dictionary.registerBoth(replace, "MSMPrompt.Replace", "MSMPrompt.Replace_Tooltip");
194
195 skip = new JButton();
196 skip.addActionListener(this);
197 skip.setEnabled(true);
198 skip.setMnemonic(KeyEvent.VK_S);
199 Dictionary.registerBoth(skip, "MSMPrompt.Skip", "MSMPrompt.Skip_Tooltip");
200
201 JList cur_values = new JList(atts_cur);
202 cur_values.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
203 cur_values.setLayoutOrientation(JList.VERTICAL);
204 cur_values.setVisibleRowCount(3);
205 cur_values.setCellRenderer(new AttributeListCellRenderer());
206 cur_values.addListSelectionListener(new ElementListListener(cur_values, replace));
207
208 // Layout
209 JPanel title_pane = new JPanel();
210 title_pane.setLayout(new GridLayout(2,2));
211 title_pane.add(element_name_label);
212 title_pane.add(element_name);
213 title_pane.add(attribute_name_label);
214 title_pane.add(attribute_name);
215
216 JPanel current_pane = new JPanel();
217 current_pane.setLayout(new BorderLayout());
218 current_pane.setBorder(BorderFactory.createTitledBorder(Dictionary.get("MSMPrompt.Current_Values")));
219 JScrollPane scroll = new JScrollPane(cur_values);
220 current_pane.add(scroll, BorderLayout.CENTER);
221
222 JPanel new_pane = new JPanel();
223 new_pane.setBorder(BorderFactory.createTitledBorder(Dictionary.get("MSMPrompt.New_Value")));
224 new_pane.setLayout(new BorderLayout());
225 JLabel new_att = new JLabel(MSMUtils.getValue(att_new));
226 new_pane.add(new_att, BorderLayout.WEST);
227 JPanel central_pane = new JPanel();
228 central_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
229 central_pane.setLayout(new BoxLayout(central_pane, BoxLayout.Y_AXIS));
230 central_pane.add(title_pane);
231 central_pane.add(current_pane);
232 central_pane.add(new_pane);
233
234 JPanel button_pane = new JPanel();
235 button_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
236 button_pane.setLayout(new GridLayout(1,4));
237 button_pane.add(add);
238 button_pane.add(replace);
239 button_pane.add(skip);
240 button_pane.add(cancel);
241
242 content_pane.setLayout(new BorderLayout());
243 content_pane.add(central_pane, BorderLayout.CENTER);
244 content_pane.add(button_pane, BorderLayout.SOUTH);
245
246 // Display
247 dialog.setLocation((screen_size.width - MDE_SIZE.width) / 2, (screen_size.height - MDE_SIZE.height) / 2);
248 on_screen = dialog;
249 on_screen.setVisible(true); // blocks until hidden
250 on_screen.dispose();
251
252 // the return value - will either be an Integer containing the action,
253 // of the selected Element for a replace
254 Object result = new Integer(action);
255 // need to get the value of the list selection if replace was clicked
256 if (action == Declarations.REPLACE) {
257 result = cur_values.getSelectedValue();
258 }
259 content_pane = null;
260 element_name_label = null;
261 element_name = null;
262 attribute_name_label = null;
263 attribute_name=null;
264 cur_values = null;
265 title_pane=null;
266 current_pane = null;
267 scroll = null;
268 new_pane = null;
269 new_att = null;
270 central_pane = null;
271 button_pane = null;
272 on_screen = null;
273 dialog = null;
274
275 return result;
276 }
277
278 /** This method displays the metadata data set merging prompt, wherein the user determines how the elements within a set should be merged.
279 * @param mds_cur The current <strong>MetadataSet</strong> containing our document.
280 * @param mde_cur The current <strong>Element</strong> we are merging against.
281 * @param mds_new The <strong>MetadataSet</strong> we are merging in.
282 * @param mde_new The <strong>Element</strong> which we have choosen to merge in.
283 * @return An <i>int</i> specifying what further action should be undertaken, if any.
284 */
285 public int mDSPrompt(MetadataSet mds_cur, Element mde_cur, MetadataSet mds_new, Element mde_new) {
286 action = Declarations.NO_ACTION;
287
288 // Construction and configuration
289 JDialog dialog = new ModalDialog(Gatherer.g_man);
290 dialog.setModal(true);
291 dialog.setSize(MDS_SIZE);
292 dialog.setJMenuBar(new SimpleMenuBar("importingpreviouslyassignedmetadata"));
293 Dictionary.setText(dialog, "MSMPrompt.Merge_MDS");
294
295 JTextArea current_details = new JTextArea();
296 Dictionary.registerText(current_details, "MSMPrompt.No_Details");
297
298 JLabel current_details_label = new JLabel();
299 Dictionary.registerText(current_details_label, "MSMPrompt.Current_Details");
300
301 JTextArea new_details = new JTextArea();
302 Dictionary.registerText(new_details, "MSMPrompt.No_Details");
303
304 JLabel new_details_label = new JLabel();
305 Dictionary.registerText(new_details_label, "MSMPrompt.New_Details");
306
307 JLabel progress_label = new JLabel();
308 Dictionary.registerText(progress_label, "MSMPrompt.Progress");
309
310 add = new JButton();
311 add.addActionListener(this);
312 add.setEnabled(false);
313 add.setMnemonic(KeyEvent.VK_A);
314 Dictionary.registerBoth(add, "MSMPrompt.Add", "MSMPrompt.Add_Tooltip");
315
316 merge = new JButton();
317 merge.addActionListener(this);
318 merge.setEnabled(true);
319 merge.setMnemonic(KeyEvent.VK_M);
320 Dictionary.registerBoth(merge, "MSMPrompt.Merge", "MSMPrompt.Merge_Tooltip");
321
322 rename = new JButton();
323 rename.addActionListener(this);
324 rename.setEnabled(false);
325 rename.setMnemonic(KeyEvent.VK_N);
326 Dictionary.registerBoth(rename, "MSMPrompt.Rename", "MSMPrompt.Rename_Tooltip");
327
328 replace = new JButton();
329 replace.addActionListener(this);
330 replace.setEnabled(false);
331 replace.setMnemonic(KeyEvent.VK_R);
332 Dictionary.registerBoth(replace, "MSMPrompt.Replace", "MSMPrompt.Replace_Tooltip");
333
334 skip = new JButton();
335 skip.addActionListener(this);
336 skip.setEnabled(true);
337 skip.setMnemonic(KeyEvent.VK_S);
338 Dictionary.registerBoth(skip, "MSMPrompt.Skip", "MSMPrompt.Skip_Tooltip");
339
340 JPanel content_pane = (JPanel)dialog.getContentPane();
341 if (mde_cur != null) {
342 add.setEnabled(false);
343 cancel.setEnabled(true);
344 merge.setEnabled(true);
345 rename.setEnabled(true);
346 replace.setEnabled(true);
347 skip.setEnabled(true);
348 // Current details.
349 String str_cur[] = MSMUtils.getStructuralDetails(mds_cur, mde_cur);
350 String opt_cur[] = MSMUtils.getOptionListDetails(mde_cur);
351 String ass_cur[] = MSMUtils.getAssignedValuesDetails(mds_cur, mde_cur);
352 String details_cur = Dictionary.get("MSMPrompt.Structural", str_cur);
353 if(opt_cur != null) {
354 details_cur = details_cur + "\n" + Dictionary.get("MSMPrompt.OptionList", opt_cur);
355 }
356 if(ass_cur != null) {
357 details_cur = details_cur + "\n" + Dictionary.get("MSMPrompt.AssignedValues", ass_cur);
358 }
359 current_details.setText(details_cur);
360 str_cur = null;
361 opt_cur = null;
362 ass_cur = null;
363 details_cur = null;
364 }
365 else {
366 add.setEnabled(true);
367 cancel.setEnabled(true);
368 merge.setEnabled(true);
369 rename.setEnabled(false);
370 replace.setEnabled(false);
371 skip.setEnabled(true);
372 Dictionary.setText(current_details, "MSMPrompt.No_Element");
373 }
374
375 // New details.
376 String str_new[] = MSMUtils.getStructuralDetails(mds_new, mde_new);
377 String opt_new[] = MSMUtils.getOptionListDetails(mde_new);
378 String ass_new[] = MSMUtils.getAssignedValuesDetails(mds_new, mde_new);
379 String details_new = Dictionary.get("MSMPrompt.Structural", str_new);
380 if(opt_new != null) {
381 details_new = details_new + "\n" + Dictionary.get("MSMPrompt.OptionList", opt_new);
382 }
383 if(ass_new != null) {
384 details_new = details_new + "\n" + Dictionary.get("MSMPrompt.AssignedValues", ass_new);
385 }
386 new_details.setText(details_new);
387
388 // Layout
389 JPanel current_details_pane = new JPanel();
390 current_details_pane.setLayout(new BorderLayout());
391 current_details_pane.add(current_details_label, BorderLayout.NORTH);
392 current_details_pane.add(new JScrollPane(current_details), BorderLayout.CENTER);
393
394 JPanel new_details_pane = new JPanel();
395 new_details_pane.setLayout(new BorderLayout());
396 new_details_pane.add(new_details_label, BorderLayout.NORTH);
397 new_details_pane.add(new JScrollPane(new_details), BorderLayout.CENTER);
398
399 JPanel details_pane = new JPanel();
400 details_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
401 details_pane.setLayout(new GridLayout(1,2));
402 details_pane.add(current_details_pane);
403 details_pane.add(new_details_pane);
404
405 JPanel button_pane = new JPanel();
406 button_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
407 button_pane.setLayout(new GridLayout(1,6));
408 button_pane.add(add);
409 button_pane.add(merge);
410 button_pane.add(rename);
411 button_pane.add(replace);
412 button_pane.add(skip);
413 button_pane.add(cancel);
414
415 JPanel control_pane = new JPanel();
416 control_pane.setLayout(new BorderLayout());
417 control_pane.add(details_pane, BorderLayout.CENTER);
418 control_pane.add(button_pane, BorderLayout.SOUTH);
419
420 JPanel progress_pane = new JPanel();
421 progress_pane.setBorder(BorderFactory.createEmptyBorder(5,5,0,5));
422 progress_pane.setLayout(new BorderLayout());
423 progress_pane.add(progress_label, BorderLayout.NORTH);
424 progress_pane.add(progress, BorderLayout.CENTER);
425
426 content_pane.setLayout(new BorderLayout());
427 content_pane.add(progress_pane, BorderLayout.NORTH);
428 content_pane.add(control_pane, BorderLayout.CENTER);
429
430 // Display
431 dialog.setLocation((screen_size.width - MDS_SIZE.width) / 2, (screen_size.height - MDS_SIZE.height) / 2);
432 on_screen = dialog;
433 on_screen.setVisible(true); // Blocks until hidden.
434 on_screen.dispose();
435 on_screen = null;
436
437 content_pane = null;
438 str_new = null;
439 opt_new = null;
440 ass_new = null;
441 details_new = null;
442 current_details_pane = null;
443 new_details_pane = null;
444 details_pane = null;
445 button_pane = null;
446 control_pane = null;
447 progress_pane = null;
448 dialog = null;
449
450 if(mde_cur == null && action == Declarations.MERGE) {
451 action = Declarations.FORCE_MERGE;
452 }
453 return action;
454 }
455
456 /** This method initialises the progress bar.
457 * @param element_count An <i>int</i> specifying the total number of elements to be merged.
458 */
459 public void startMerge(int element_count) {
460 progress.setMaximum(element_count);
461 progress.setMinimum(0);
462 progress.setString("0%");
463 progress.setValue(0);
464 }
465
466 /** This method creates a prompt for renaming an Element.
467 * @param mde_new The <strong>Element</strong> we wish to rename.
468 * @return The new name as a <strong>String</strong>, <i>null</i> if cancelled.
469 */
470 public String rename(Element mde_new) {
471 action = Declarations.NO_ACTION;
472
473 // Create
474 JDialog dialog = new ModalDialog(Gatherer.g_man);
475 dialog.setModal(true);
476 dialog.setSize(RENAME_SIZE);
477 dialog.setJMenuBar(new SimpleMenuBar("importingpreviouslyassignedmetadata"));
478 Dictionary.setText(dialog, "MSMPrompt.Rename");
479
480 JLabel old_name_label = new JLabel();
481 old_name_label.setPreferredSize(RENAME_LABEL_SIZE);
482 Dictionary.setText(old_name_label, "MSMPrompt.Old_Name");
483
484 JLabel old_name = new JLabel(mde_new.getAttribute("name"));
485 old_name.setBackground(Color.white);
486 old_name.setOpaque(true);
487
488 JLabel new_name_label = new JLabel();
489 new_name_label.setPreferredSize(RENAME_LABEL_SIZE);
490 Dictionary.setText(new_name_label, "MSMPrompt.New_Name");
491
492 JTextField new_name = new JTextField("");
493 new_name.grabFocus();
494 Dictionary.setTooltip(new_name, "MSMPrompt.New_Name_Tooltip");
495
496 JButton ok = new JButton();
497 ok.addActionListener(this);
498 ok.setMnemonic(KeyEvent.VK_O);
499 Dictionary.setBoth(ok, "General.OK", "General.OK_Tooltip");
500
501 JPanel content_pane = (JPanel) dialog.getContentPane();
502
503 // Layout
504 JPanel old_name_pane = new JPanel();
505 old_name_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
506 old_name_pane.setLayout(new BorderLayout());
507 old_name_pane.add(old_name_label, BorderLayout.WEST);
508 old_name_pane.add(old_name, BorderLayout.CENTER);
509
510 JPanel new_name_pane = new JPanel();
511 new_name_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
512 new_name_pane.setLayout(new BorderLayout());
513 new_name_pane.add(new_name_label, BorderLayout.WEST);
514 new_name_pane.add(new_name, BorderLayout.CENTER);
515
516 JPanel control_pane = new JPanel();
517 control_pane.setLayout(new GridLayout(2,1));
518 control_pane.add(old_name_pane);
519 control_pane.add(new_name_pane);
520
521 JPanel button_pane = new JPanel();
522 button_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
523 button_pane.setLayout(new GridLayout(1,2));
524 button_pane.add(ok);
525 button_pane.add(cancel);
526
527 content_pane.setLayout(new BorderLayout());
528 content_pane.add(control_pane, BorderLayout.CENTER);
529 content_pane.add(button_pane, BorderLayout.SOUTH);
530
531 // Display
532 dialog.setLocation((screen_size.width - RENAME_SIZE.width) / 2, (screen_size.height - RENAME_SIZE.height) / 2);
533 on_screen = dialog;
534 on_screen.setVisible(true);
535 on_screen.dispose();
536 on_screen = null;
537
538 String result = new_name.getText();
539 button_pane = null;
540 control_pane = null;
541 new_name_pane = null;
542 old_name_pane = null;
543 content_pane = null;
544 ok.removeActionListener(this);
545 ok = null;
546 new_name = null;
547 new_name_label = null;
548 old_name = null;
549 old_name_label = null;
550 dialog = null;
551
552 if(action == Declarations.CANCEL) {
553 return null;
554 }
555 action = Declarations.NO_ACTION;
556 dialog = null;
557 return result;
558 }
559
560 /** When called this method produces a nice error message on the screen, advising the user that the remove action has failed.
561 * @param mde_cur The <strong>Element</strong> that we are attempting to remove.
562 * @param reason The phrase key for the reason the rename failed, also as a <strong>String</strong>.
563 */
564 public void removeFailed(Element mde_cur, String reason) {
565 String args[] = new String[2];
566 args[0] = mde_cur.getAttribute("name");
567 args[1] = Dictionary.get(reason);
568 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("MSMPrompt.Remove_Failed", args), Dictionary.get("MSMPrompt.Remove_Failed_Title"), JOptionPane.ERROR_MESSAGE);
569 }
570
571 /** When called this method produces a nice error message on the screen, advising the user that the rename action has failed.
572 * @param mde_new The <strong>Element</strong> that we are attempting to add.
573 * @param new_name The name that we attempted to add it under, as a <strong>String</strong>.
574 * @param reason The phrase key for the reason the rename failed, also as a <strong>String</strong>.
575 */
576 public void renameFailed(Element mde_new, String new_name, String reason) {
577 String args[] = new String[3];
578 args[0] = mde_new.getAttribute("name");
579 args[1] = new_name;
580 args[2] = Dictionary.get(reason);
581 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("MSMPrompt.Rename_Failed", args), Dictionary.get("MSMPrompt.Rename_Failed_Title"), JOptionPane.ERROR_MESSAGE);
582 }
583
584 /** Method to display a prompt asking the user to select a specific element to merge with.
585 * @param mds_cur The current <strong>MetadataSet</strong>.
586 * @return The selected <strong>Element</strong> or <i>null</i> if the user cancels the action.
587 */
588 public Element selectElement(MetadataSet mds_cur) {
589 action = Declarations.NO_ACTION;
590
591 // Create
592 JDialog dialog = new ModalDialog(Gatherer.g_man);
593 dialog.setModal(true);
594 dialog.setSize(SELECT_SIZE);
595 dialog.setJMenuBar(new SimpleMenuBar("importingpreviouslyassignedmetadata"));
596 Dictionary.setText(dialog, "MSMPrompt.Select");
597
598 JButton ok = new JButton();
599 ok.addActionListener(this);
600 ok.setMnemonic(KeyEvent.VK_O);
601 ok.setEnabled(false);
602 Dictionary.setBoth(ok, "General.OK", "General.OK_Tooltip");
603
604 Node elements_raw[] = ArrayTools.nodeListToNodeArray(mds_cur.getElements());
605 ElementWrapper elements[] = new ElementWrapper[elements_raw.length];
606 for(int i = 0; i < elements_raw.length; i++) {
607 elements[i] = new ElementWrapper((Element)elements_raw[i]);
608 }
609 JList list = new JList(elements);
610 ElementListListener element_list_listener = new ElementListListener(list, ok);
611 list.addListSelectionListener(element_list_listener);
612 JPanel content_pane = (JPanel) dialog.getContentPane();
613
614 // Layout
615 JPanel list_pane = new JPanel();
616 list_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
617 list_pane.setLayout(new BorderLayout());
618 list_pane.add(new JScrollPane(list), BorderLayout.CENTER);
619
620 JPanel button_pane = new JPanel();
621 button_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
622 button_pane.setLayout(new GridLayout(1,2));
623 button_pane.add(ok);
624 button_pane.add(cancel);
625
626 content_pane.setLayout(new BorderLayout());
627 content_pane.add(list_pane, BorderLayout.CENTER);
628 content_pane.add(button_pane, BorderLayout.SOUTH);
629
630 // Display
631 dialog.setLocation((screen_size.width - SELECT_SIZE.width) / 2, (screen_size.height - SELECT_SIZE.height) / 2);
632 on_screen = dialog;
633 on_screen.setVisible(true);
634 on_screen.dispose();
635 on_screen = null;
636
637 // get the result
638 Element result = ((ElementWrapper)list.getSelectedValue()).getElement();
639 // Deallocate stuff since JDK1.4 won't.
640 ok.removeActionListener(this);
641 ok = null;
642 elements_raw = null;
643 elements = null;
644 list.removeListSelectionListener(element_list_listener);
645 list = null;
646 element_list_listener = null;
647 content_pane = null;
648 list_pane = null;
649 button_pane = null;
650 dialog = null;
651 // Return selected element
652 if(action == Declarations.CANCEL) {
653 return null;
654 }
655 return result;
656 }
657
658 /** Prompts the user to choose how to import a metadata element. Gives the option of renaming the element to a certain value of a certain set, or adding to a selected set.
659 * @param name The name of the original metadata as a String.
660 * @param set The set previously choosen as the default set for this metadata (which it doesn't match somehow).
661 * @return An ElementWrapper around the element that it has been matched to.
662 * @see org.greenstone.gatherer.msm.MSMPrompt.MSMDialog
663 */
664 public ElementWrapper selectElement(String name) {
665 dialog_cancelled = false;
666 result = null;
667 String args[] = new String[1];
668 args[0] = name;
669
670 // Create
671 MSMDialog dialog = new MSMDialog();
672 dialog.setModal(true);
673 dialog.setSize(SELECT_ELEMENT_SIZE);
674 dialog.setJMenuBar(new SimpleMenuBar("importingpreviouslyassignedmetadata"));
675 Dictionary.setText(dialog, "MSMPrompt.Select_Element_Title");
676
677 JPanel content_pane = (JPanel) dialog.getContentPane();
678 JPanel control_pane = new JPanel();
679 JTextArea instructions = new JTextArea();
680 instructions.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
681 instructions.setEditable(false);
682 instructions.setLineWrap(true);
683 instructions.setRows(SELECT_LINE_COUNT);
684 instructions.setWrapStyleWord(true);
685 Dictionary.setText(instructions, "MSMPrompt.Select_Element_Instructions", args);
686
687 JPanel original_pane = new JPanel();
688 JLabel original_label = new JLabel();
689 original_label.setPreferredSize(SELECT_LABEL_SIZE);
690 Dictionary.setText(original_label, "MSMPrompt.Select_Element_Original");
691 JTextField original = new JTextField(name);
692 original.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
693 original.setEditable(false);
694
695 JPanel set_pane = new JPanel();
696 JLabel set_label = new JLabel();
697 set_label.setPreferredSize(SELECT_LABEL_SIZE);
698 Dictionary.setText(set_label, "MSMPrompt.Select_Element_Set");
699 JComboBox set = new JComboBox(manager.getSets(false)); // Don't include the greenstone metadata set.
700 Dictionary.setTooltip(set, "MSMPrompt.Select_Element_Set_Tooltip");
701
702 JPanel element_pane = new JPanel();
703 JLabel element_label = new JLabel();
704 element_label.setPreferredSize(SELECT_LABEL_SIZE);
705 Dictionary.setText(element_label, "MSMPrompt.Select_Element_Element");
706 JComboBox element = new JComboBox();
707 Dictionary.setTooltip(element, "MSMPrompt.Select_Element_Element_Tooltip");
708
709 JButton add_button = new JButton();
710 add_button.setEnabled(false);
711 add_button.setMnemonic(KeyEvent.VK_A);
712 Dictionary.setBoth(add_button, "MSMPrompt.Select_Element_Add", "MSMPrompt.Select_Element_Add_Tooltip");
713
714 JButton cancel_button = new JButton();
715 cancel_button.setMnemonic(KeyEvent.VK_C);
716 Dictionary.setBoth(cancel_button, "General.Cancel", "General.Cancel_Tooltip");
717
718 JButton merge_button = new JButton();
719 merge_button.setEnabled(false);
720 merge_button.setMnemonic(KeyEvent.VK_M);
721 Dictionary.setBoth(merge_button, "MSMPrompt.Select_Element_Merge", "MSMPrompt.Select_Element_Merge_Tooltip");
722
723 JButton ignore_button = new JButton();
724 ignore_button.setMnemonic(KeyEvent.VK_I);
725 Dictionary.setBoth(ignore_button, "MSMPrompt.Select_Element_Ignore", "MSMPrompt.Select_Element_Ignore_Tooltip");
726
727 JPanel button_pane = new JPanel();
728
729 // Connect
730 AddListener add_listener = new AddListener(dialog, name, set);
731 CancelListener cancel_listener = new CancelListener(dialog);
732 IgnoreListener ignore_listener = new IgnoreListener(dialog);
733 MergeListener merge_listener = new MergeListener(dialog, element);
734 SetListener set_listener = new SetListener(set, element, name, add_button, merge_button);
735
736 add_button.addActionListener(add_listener);
737 cancel_button.addActionListener(cancel_listener);
738 merge_button.addActionListener(merge_listener);
739 ignore_button.addActionListener(ignore_listener);
740 set.addActionListener(set_listener);
741
742 // Init controls
743 if(set.getItemCount() > 0) {
744 // We now try to determine if there is any existing metadata
745 // element whose name is the same as the new one. we ignore
746 // any namespaces - if the name was a full match (namespace
747 // and element name) then we wouldn't be in here
748 MetadataSet closest_set = null;
749 ElementWrapper closest_element = null;
750 String base_name = name;
751 int ns_sep = base_name.indexOf(MSMUtils.NS_SEP);
752 if (ns_sep != -1) {
753 base_name = base_name.substring(ns_sep+1);
754 }
755 for(int i = 0; i < set.getItemCount(); i++) {
756 MetadataSet mds = (MetadataSet) set.getItemAt(i);
757 for(int j = 0; j < mds.size(); j++) {
758 Element mde = mds.getElement(j);
759 String new_name = mde.getAttribute("name");
760 if (base_name.equals(new_name)) {
761 closest_element = new ElementWrapper(mde);
762 closest_set = mds;
763 mde=null;
764 break;
765 }
766 mde = null;
767 } // for each element
768 if (closest_element != null) {
769 mds=null;
770 break;
771 }
772
773 mds = null;
774 } // for each set
775 if(closest_set != null && closest_element != null) {
776 set.setSelectedItem(closest_set);
777 set_listener.actionPerformed(closest_element);
778 }
779 else {
780 set_listener.actionPerformed((ElementWrapper)null);
781 }
782 closest_set = null;
783 closest_element = null;
784 }
785 merge_button.setEnabled(element.getItemCount() > 0);
786
787 // Layout
788 original_label.setBorder(BorderFactory.createEmptyBorder(0,0,0,5));
789 original_pane.setLayout(new BorderLayout());
790 original_pane.add(original_label, BorderLayout.WEST);
791 original_pane.add(original, BorderLayout.CENTER);
792 set_label.setBorder(BorderFactory.createEmptyBorder(0,0,0,5));
793 set_pane.setLayout(new BorderLayout());
794 set_pane.add(set_label, BorderLayout.WEST);
795 set_pane.add(set, BorderLayout.CENTER);
796 element_label.setBorder(BorderFactory.createEmptyBorder(0,0,0,5));
797 element_pane.setLayout(new BorderLayout());
798 element_pane.add(element_label, BorderLayout.WEST);
799 element_pane.add(element, BorderLayout.CENTER);
800 control_pane.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
801 control_pane.setLayout(new GridLayout(3,1));
802 control_pane.add(original_pane);
803 control_pane.add(set_pane);
804 control_pane.add(element_pane);
805 button_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
806 button_pane.setLayout(new GridLayout(1,4));
807 button_pane.add(add_button);
808 button_pane.add(merge_button);
809 button_pane.add(ignore_button);
810 button_pane.add(cancel_button);
811 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
812 content_pane.setLayout(new BorderLayout());
813 content_pane.add(new JScrollPane(instructions), BorderLayout.NORTH);
814 content_pane.add(control_pane, BorderLayout.CENTER);
815 content_pane.add(button_pane, BorderLayout.SOUTH);
816
817 // Display
818 dialog.setLocation((screen_size.width - SELECT_ELEMENT_SIZE.width) / 2, (screen_size.height - SELECT_ELEMENT_SIZE.height) / 2);
819 dialog.setVisible(true);
820 // Deallocate everything because JDK1.4 won't.
821 // Why, oh why did I do this?
822 add_button.removeActionListener(add_listener);
823 merge_button.removeActionListener(merge_listener);
824 ignore_button.removeActionListener(ignore_listener);
825 add_button = null;
826 merge_button = null;
827 ignore_button = null;
828 add_listener = null;
829 merge_listener = null;
830 ignore_listener = null;
831 // References
832 args = null;
833 content_pane = null;
834 control_pane = null;
835 instructions = null;
836 original_pane = null;
837 original_pane = null;
838 original = null;
839 element_pane = null;
840 element_label = null;
841 element = null;
842 set_pane = null;
843 set_label = null;
844 set.removeActionListener(set_listener);
845 set_listener = null;
846 set = null;
847 button_pane = null;
848 dialog.dispose();
849 dialog.destroy();
850 dialog = null;
851 // Dondage.
852 return (ElementWrapper)result;
853 }
854
855 public boolean wasDialogCancelled() {
856 return dialog_cancelled;
857 }
858
859 /** Prompts the user to select a metadata set from the given list. Uses the name parameter to attempt to automatically select the correct collection (ie the only collection that has an element with the same name).
860 * @param name The name of the metadata element whose set name is unknown.
861 * @return The metadata set the user has selected or null if no set selected.
862 */
863 final public MetadataSet selectSet(String name) {
864 String args[] = new String[1];
865 args[0] = name;
866
867 // Creation
868 MSMDialog dialog = new MSMDialog();
869 dialog.setModal(true);
870 dialog.setSize(SELECT_SET_SIZE);
871 dialog.setJMenuBar(new SimpleMenuBar("importingpreviouslyassignedmetadata"));
872 Dictionary.setText(dialog, "MSMPrompt.Select_Set_Title");
873
874 JPanel content_pane = (JPanel) dialog.getContentPane();
875 JPanel control_pane = new JPanel();
876 JTextArea instructions = new JTextArea();
877 instructions.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
878 instructions.setEditable(false);
879 instructions.setLineWrap(true);
880 instructions.setRows(SELECT_LINE_COUNT);
881 instructions.setWrapStyleWord(true);
882 Dictionary.setText(instructions, "MSMPrompt.Select_Set_Instructions", args);
883
884 JComboBox set = new JComboBox();
885 set.setBackground(Color.white);
886 set.addItem(Dictionary.get("MSMPrompt.Select_Set_None"));
887 Vector sets = manager.getSets();
888 for(int i = sets.size() - 1; i >= 0; i--) {
889 set.addItem(sets.get(i));
890 }
891 Dictionary.setTooltip(set, "MSMPrompt.Select_Element_Set_Tooltip");
892
893 JButton ok = new JButton();
894 ActionListener ok_listener = new IgnoreListener(dialog);
895 ok.addActionListener(ok_listener); // Doesn't really ignore. Just disposes()
896 Dictionary.setBoth(ok, "General.OK", "General.OK_Tooltip");
897
898 // Select most likely set
899 if(name.indexOf(".") != -1) {
900 String set_name = name.substring(0, name.indexOf("."));
901 MetadataSet metadata_set = manager.getSet(set_name);
902 if(metadata_set != null) {
903 set.setSelectedItem(metadata_set);
904 }
905 metadata_set = null;
906 set_name = null;
907 }
908 else {
909 Vector matches = manager.setsThatContain(name);
910 if(matches.size() == 1) {
911 set.setSelectedItem(matches.get(0));
912 }
913 matches = null;
914 }
915
916 // Layout
917 control_pane.setLayout(new GridLayout(2,1));
918 control_pane.add(set);
919 control_pane.add(ok);
920 content_pane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
921 content_pane.setLayout(new BorderLayout());
922 content_pane.add(new JScrollPane(instructions), BorderLayout.CENTER);
923 content_pane.add(control_pane, BorderLayout.SOUTH);
924
925 // Display
926 dialog.setLocation((screen_size.width - SELECT_SET_SIZE.width) / 2, (screen_size.height - SELECT_SET_SIZE.height) / 2);
927 dialog.setVisible(true);
928 Object value = set.getSelectedItem();
929 if(value instanceof MetadataSet) {
930 return (MetadataSet) value;
931 }
932 value = null;
933 ok.removeActionListener(ok_listener);
934 ok_listener = null;
935 ok = null;
936 content_pane = null;
937 control_pane = null;
938 instructions = null;
939 set = null;
940 dialog.destroy();
941 dialog = null;
942 return null;
943 }
944
945 private class AddListener
946 implements ActionListener {
947 private JComboBox set = null;
948 private JDialog dialog = null;
949 private String name = null;
950 public AddListener(JDialog dialog, String name, JComboBox set) {
951 this.dialog = dialog;
952 this.name = name;
953 this.set = set;
954 }
955 public void actionPerformed(ActionEvent event) {
956 // Get the currently selected metadata set.
957 MetadataSet mds = (MetadataSet) set.getSelectedItem();
958 String n = name;
959 // If we've been forced to go this far then any given namespace is complete bollocks.
960 while(n.indexOf(".") != -1 && !n.equals(".")) {
961 n = n.substring(n.indexOf(".") + 1);
962 }
963 // However, before we attempt to add a new element to the set, we should check that none already exists.
964 Element element = mds.getElement(name);
965 if (element == null) {
966 result = mds.addElement(n, Gatherer.config.interface_language);
967 }
968 else {
969 result = (ElementWrapper) element;
970 }
971 mds = null;
972 n = null;
973 element = null;
974 dialog.setVisible(false);
975 }
976 }
977
978 /** a ListCellRenderer for a list of Elements - the displayed value of the element is not Element.toString() */
979 private class AttributeListCellRenderer extends DefaultListCellRenderer {
980
981 public AttributeListCellRenderer() {
982 super();
983 }
984 public Component getListCellRendererComponent(JList list,
985 Object value,
986 int index,
987 boolean isSelected,
988 boolean cellHasFocus) {
989
990 setText(MSMUtils.getValue((Element)value));
991 if (isSelected) {
992 setBackground(list.getSelectionBackground());
993 setForeground(list.getSelectionForeground());
994 }
995 else {
996 setBackground(list.getBackground());
997 setForeground(list.getForeground());
998 }
999 setEnabled(list.isEnabled());
1000 setFont(list.getFont());
1001 setOpaque(true);
1002 return this;
1003 }
1004
1005
1006 }
1007
1008 /** This listener listens for selections within the select element to merge prompt, and once one has been made enables the ok button.*/
1009 private class ElementListListener
1010 implements ListSelectionListener {
1011 /** The button we either enable or disable depending on user selection. */
1012 private JButton ok = null;
1013 /** The list from whom we are listening for selection events. */
1014 private JList list = null;
1015 /** Constructor.
1016 * @param list The <strong>JList</Strong> from whom we are listening for selection events.
1017 * @param ok The <Strong>JButton</strong> we either enable or disable depending on user selection.
1018 */
1019 public ElementListListener(JList list, JButton ok) {
1020 this.list = list;
1021 this.ok = ok;
1022 }
1023 /** Any implementation of <i>ListSelectionListener</i> must include this method so we can be informed when a list selection event has occured.
1024 * @param event A <strong>ListSelectionEvent</strong> generated by the event.
1025 */
1026 public void valueChanged(ListSelectionEvent event) {
1027 if(list.getSelectedValue() != null) {
1028 ok.setEnabled(true);
1029 }
1030 else {
1031 ok.setEnabled(false);
1032 }
1033 }
1034 }
1035
1036 private class CancelListener
1037 implements ActionListener {
1038 private JDialog dialog = null;
1039 public CancelListener(JDialog dialog) {
1040 this.dialog = dialog;
1041 }
1042 public void actionPerformed(ActionEvent event) {
1043 dialog_cancelled = true;
1044 dialog.setVisible(false);
1045 }
1046 }
1047
1048 private class IgnoreListener
1049 implements ActionListener {
1050 private JDialog dialog = null;
1051 public IgnoreListener(JDialog dialog) {
1052 this.dialog = dialog;
1053 }
1054 public void actionPerformed(ActionEvent event) {
1055 dialog.setVisible(false);
1056 }
1057 }
1058
1059 private class MergeListener
1060 implements ActionListener {
1061 private JComboBox element = null;
1062 private JDialog dialog = null;
1063 public MergeListener(JDialog dialog, JComboBox element) {
1064 this.dialog = dialog;
1065 this.element = element;
1066 }
1067 public void actionPerformed(ActionEvent event) {
1068 // Return the currently selected element
1069 result = (ElementWrapper)element.getSelectedItem();
1070 dialog.setVisible(false);
1071 }
1072 }
1073
1074 private class MSMDialog
1075 extends ModalDialog {
1076
1077 public MSMDialog() {
1078 super(Gatherer.g_man);
1079 }
1080 public void destroy() {
1081 rootPane = null;
1082 }
1083 }
1084
1085 /** Listens to changes in the metadata set combobox */
1086 private class SetListener
1087 implements ActionListener {
1088
1089 private JButton add_button = null;
1090 private JButton merge_button = null;
1091 private JComboBox element_combobox = null;
1092 private JComboBox set_combobox = null;
1093 private String element_name = null;
1094
1095 public SetListener(JComboBox set_combobox, JComboBox element_combobox, String element_name, JButton add_button, JButton merge_button)
1096 {
1097 this.element_name = element_name;
1098 this.element_combobox = element_combobox;
1099 this.set_combobox = set_combobox;
1100 this.add_button = add_button;
1101 this.merge_button = merge_button;
1102 }
1103
1104 /** because the dialog constructor is selecting an element before calling actionPerformed, and actionPerformed is where the list of elements is built, we need to tell this what element should be selected */
1105 public void actionPerformed(ElementWrapper selected_elem)
1106 {
1107 MetadataSet mds = (MetadataSet) set_combobox.getSelectedItem();
1108 if (mds == null) {
1109 // If there is no metadata set selected, there isn't much you can do
1110 add_button.setEnabled(false);
1111 merge_button.setEnabled(false);
1112 return;
1113 }
1114
1115 // Fill the element combobox with the elements of the selected metadata set
1116 element_combobox.removeAllItems();
1117 Vector elements_list = mds.getElementsSorted();
1118 for (int i = 0; i < elements_list.size(); i++) {
1119 element_combobox.addItem(elements_list.get(i));
1120 }
1121
1122 // If there is a pre-selected element, select it in the combobox
1123 if (selected_elem != null) {
1124 // If the element is not in the set, the selection won't change
1125 element_combobox.setSelectedItem(selected_elem);
1126 }
1127
1128 // Can only add if the element doesn't already exist in the metadata set
1129 add_button.setEnabled(!mds.containsElement(element_name));
1130
1131 // Can only merge if the metadata set is not empty
1132 merge_button.setEnabled(mds.size() > 0);
1133 }
1134
1135 public void actionPerformed(ActionEvent item)
1136 {
1137 actionPerformed((ElementWrapper) null);
1138 }
1139 }
1140}
Note: See TracBrowser for help on using the repository browser.