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

Last change on this file since 7992 was 7609, checked in by kjdon, 20 years ago

fixed the bug where when you drag a document with existing namespaced metadata into a collection with a different metadata set, the add button would be enabled for metadata with the same name as an existing one. the problem was, the namespace wasn't being removed before testing to see if it existed.

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