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

Last change on this file since 6877 was 6770, checked in by kjdon, 20 years ago

fixed all the javadoc errors. (hope I didn't commit anything I wasn't supposed to)

  • 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 // 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 GLIButton();
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 GLIButton();
715 cancel_button.setMnemonic(KeyEvent.VK_C);
716 Dictionary.setBoth(cancel_button, "General.Cancel", "General.Cancel_Tooltip");
717
718 JButton merge_button = new GLIButton();
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 GLIButton();
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 private class AddListener
860 implements ActionListener {
861 private JComboBox set = null;
862 private JDialog dialog = null;
863 private String name = null;
864 public AddListener(JDialog dialog, String name, JComboBox set) {
865 this.dialog = dialog;
866 this.name = name;
867 this.set = set;
868 }
869 public void actionPerformed(ActionEvent event) {
870 // Get the currently selected metadata set.
871 MetadataSet mds = (MetadataSet) set.getSelectedItem();
872 String n = name;
873 // If we've been forced to go this far then any given namespace is complete bollocks.
874 while(n.indexOf(".") != -1 && !n.equals(".")) {
875 n = n.substring(n.indexOf(".") + 1);
876 }
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(n, Gatherer.config.getLanguage());
881 }
882 else {
883 result = (ElementWrapper) element;
884 }
885 mds = null;
886 n = null;
887 element = null;
888 dialog.setVisible(false);
889 }
890 }
891
892 /** a ListCellRenderer for a list of Elements - the displayed value of the element is not Element.toString() */
893 private class AttributeListCellRenderer extends DefaultListCellRenderer {
894
895 public AttributeListCellRenderer() {
896 super();
897 }
898 public Component getListCellRendererComponent(JList list,
899 Object value,
900 int index,
901 boolean isSelected,
902 boolean cellHasFocus) {
903
904 setText(MSMUtils.getValue((Element)value));
905 if (isSelected) {
906 setBackground(list.getSelectionBackground());
907 setForeground(list.getSelectionForeground());
908 }
909 else {
910 setBackground(list.getBackground());
911 setForeground(list.getForeground());
912 }
913 setEnabled(list.isEnabled());
914 setFont(list.getFont());
915 setOpaque(true);
916 return this;
917 }
918
919
920 }
921
922 /** This listener listens for selections within the select element to merge prompt, and once one has been made enables the ok button.*/
923 private class ElementListListener
924 implements ListSelectionListener {
925 /** The button we either enable or disable depending on user selection. */
926 private JButton ok = null;
927 /** The list from whom we are listening for selection events. */
928 private JList list = null;
929 /** Constructor.
930 * @param list The <strong>JList</Strong> from whom we are listening for selection events.
931 * @param ok The <Strong>JButton</strong> we either enable or disable depending on user selection.
932 */
933 public ElementListListener(JList list, JButton ok) {
934 this.list = list;
935 this.ok = ok;
936 }
937 /** Any implementation of <i>ListSelectionListener</i> must include this method so we can be informed when a list selection event has occured.
938 * @param event A <strong>ListSelectionEvent</strong> generated by the event.
939 */
940 public void valueChanged(ListSelectionEvent event) {
941 if(list.getSelectedValue() != null) {
942 ok.setEnabled(true);
943 }
944 else {
945 ok.setEnabled(false);
946 }
947 }
948 }
949
950 private class CancelListener
951 implements ActionListener {
952 private JDialog dialog = null;
953 public CancelListener(JDialog dialog) {
954 this.dialog = dialog;
955 }
956 public void actionPerformed(ActionEvent event) {
957 dialog_cancelled = true;
958 dialog.setVisible(false);
959 }
960 }
961
962 private class IgnoreListener
963 implements ActionListener {
964 private JDialog dialog = null;
965 public IgnoreListener(JDialog dialog) {
966 this.dialog = dialog;
967 }
968 public void actionPerformed(ActionEvent event) {
969 dialog.setVisible(false);
970 }
971 }
972
973 private class MergeListener
974 implements ActionListener {
975 private JComboBox element = null;
976 private JDialog dialog = null;
977 public MergeListener(JDialog dialog, JComboBox element) {
978 this.dialog = dialog;
979 this.element = element;
980 }
981 public void actionPerformed(ActionEvent event) {
982 // Return the currently selected element
983 result = (ElementWrapper)element.getSelectedItem();
984 dialog.setVisible(false);
985 }
986 }
987
988 private class MSMDialog
989 extends ModalDialog {
990
991 public MSMDialog() {
992 super(Gatherer.g_man);
993 }
994 public void destroy() {
995 rootPane = null;
996 }
997 }
998
999 /** Listens to changes in the metadata set combobox */
1000 private class SetListener
1001 implements ActionListener {
1002
1003 private JButton add_button = null;
1004 private JButton merge_button = null;
1005 private JComboBox element_combobox = null;
1006 private JComboBox set_combobox = null;
1007 private String element_name = null;
1008
1009 public SetListener(JComboBox set_combobox, JComboBox element_combobox, String element_name, JButton add_button, JButton merge_button)
1010 {
1011 this.element_name = element_name;
1012 this.element_combobox = element_combobox;
1013 this.set_combobox = set_combobox;
1014 this.add_button = add_button;
1015 this.merge_button = merge_button;
1016 }
1017
1018 /** 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 */
1019 public void actionPerformed(ElementWrapper selected_elem)
1020 {
1021 MetadataSet mds = (MetadataSet) set_combobox.getSelectedItem();
1022 if (mds == null) {
1023 // If there is no metadata set selected, there isn't much you can do
1024 add_button.setEnabled(false);
1025 merge_button.setEnabled(false);
1026 return;
1027 }
1028
1029 // Fill the element combobox with the elements of the selected metadata set
1030 element_combobox.removeAllItems();
1031 Vector elements_list = mds.getElementsSorted();
1032 for (int i = 0; i < elements_list.size(); i++) {
1033 element_combobox.addItem(elements_list.get(i));
1034 }
1035
1036 // If there is a pre-selected element, select it in the combobox
1037 if (selected_elem != null) {
1038 // If the element is not in the set, the selection won't change
1039 element_combobox.setSelectedItem(selected_elem);
1040 }
1041
1042 // Can only add if the element doesn't already exist in the metadata set
1043 add_button.setEnabled(!mds.containsElement(element_name));
1044
1045 // Can only merge if the metadata set is not empty
1046 merge_button.setEnabled(mds.size() > 0);
1047 }
1048
1049 public void actionPerformed(ActionEvent item)
1050 {
1051 actionPerformed((ElementWrapper) null);
1052 }
1053 }
1054}
Note: See TracBrowser for help on using the repository browser.