View Javadoc

1   /*
2    * $Id$
3    *
4    * The contents of this file are subject to the Mozilla Public License 
5    * Version 1.1 (the "License"); you may not use this file except in 
6    * compliance with the License. You may obtain a copy of the License at 
7    * http://www.mozilla.org/MPL/ 
8    *
9    * Software distributed under the License is distributed on an "AS IS" basis, 
10   * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
11   * for the specific language governing rights and limitations under the License.
12   *
13   * The Original Code is XML Hammer code. (org.xmlhammer.*)
14   *
15   * The Initial Developer of the Original Code is Edwin Dankert. Portions created 
16   * by the Initial Developer are Copyright (C) 2005 - 2006 the Initial Developer. 
17   * All Rights Reserved.
18   *
19   * Contributor(s): Edwin Dankert <edankert@gmail.com>
20   */
21  
22  package org.xmlhammer.gui.util;
23  
24  import java.awt.BorderLayout;
25  import java.awt.Component;
26  import java.awt.Dimension;
27  import java.awt.FlowLayout;
28  import java.awt.event.ActionEvent;
29  import java.awt.event.ActionListener;
30  import java.net.URI;
31  import java.util.ArrayList;
32  import java.util.List;
33  
34  import javax.swing.ImageIcon;
35  import javax.swing.JButton;
36  import javax.swing.JFileChooser;
37  import javax.swing.JLabel;
38  import javax.swing.JPanel;
39  import javax.swing.undo.AbstractUndoableEdit;
40  
41  import org.bounce.FormLayout;
42  import org.bounce.image.ImageLoader;
43  import org.bounce.util.URIUtils;
44  import org.xmlhammer.gui.FieldManager;
45  import org.xmlhammer.gui.Page;
46  import org.xmlhammer.gui.history.HistoryComboBoxModel;
47  import org.xmlhammer.gui.history.HistoryListModel;
48  import org.xmlhammer.gui.overview.OverviewNode;
49  import org.xmlhammer.gui.overview.OverviewTreeModel;
50  import org.xmlhammer.model.project.Document;
51  import org.xmlhammer.model.project.Parameter;
52  import org.xmlhammer.model.project.ParameterisedDocument;
53  import org.xmlhammer.model.project.ParameterisedSource;
54  import org.xmlhammer.model.project.Result;
55  import org.xmlhammer.model.project.Source;
56  
57  /***
58   * Input Panel.
59   * 
60   * Allows to select either one URI, multiple URIs or 
61   * a range of files.
62   * 
63   * @version $Revision$, $Date$
64   * @author Edwin Dankert <edankert@gmail.com>
65   */
66  
67  public class URIsPanel extends JPanel implements ActionListener {
68  	private static final long serialVersionUID = 3257852090755134776L;
69  
70      static final ImageIcon TEXT_FIELD_ICON = ImageLoader.get().getImage( "/org/xmlhammer/gui/icons/elcl16/textfield_obj.gif");
71  	private static final ImageIcon REMOVE_ICON = ImageLoader.get().getImage( "/org/xmlhammer/gui/icons/elcl16/remove_att.gif");
72  
73      private ArrayList<OverviewNode> nodes                       = null;
74  	private ArrayList<RemovableURISelectionPane> uriSelectors 	= null;
75  	private JFileChooser chooser 	= null;
76  	private JButton addButton 		= null;
77  	private Page page 		        = null;
78      private JPanel urisPanel        = null;
79      private int labelWidth          = -1;
80      private boolean resultEnabled   = false;
81      private boolean parameters   = false;
82      private OverviewNode parentNode = null;
83      private HistoryListModel listModel = null;
84  
85      public URIsPanel(Page parent, HistoryListModel listModel, boolean resultEnabled) {
86          this(parent, parent, listModel, new JFileChooser(), -1, resultEnabled, false);
87      }
88  
89      public URIsPanel(Page parent, HistoryListModel listModel, boolean resultEnabled, boolean parameters) {
90          this(parent, parent, listModel, new JFileChooser(), -1, resultEnabled, parameters);
91      }
92  
93      public URIsPanel(Page page, OverviewNode parentNode, HistoryListModel listModel, JFileChooser chooser, int labelWidth) {
94          this(page, parentNode, listModel, chooser, labelWidth, false, false);
95      }
96  
97      public URIsPanel(Page page, OverviewNode parentNode, HistoryListModel listModel, JFileChooser chooser, int labelWidth, boolean parameters) {
98          this(page, parentNode, listModel, chooser, labelWidth, false, parameters);
99      }
100 
101     /***
102 	 * Constructs a new Input Panel.
103 	 */
104 	public URIsPanel(Page page, OverviewNode parentNode, HistoryListModel listModel, JFileChooser chooser, int labelWidth, boolean resultEnabled, boolean parameters) {
105 		super(new BorderLayout( 0, 10));
106 		
107 		this.page = page;
108         this.labelWidth = labelWidth;
109         this.parentNode = parentNode;
110         this.listModel = listModel;
111         this.parameters = parameters;
112         this.resultEnabled = resultEnabled;
113 
114         nodes = new ArrayList<OverviewNode>();
115 		uriSelectors = new ArrayList<RemovableURISelectionPane>();
116 
117 		urisPanel = new JPanel( new FormLayout( 0, 5));
118 		this.chooser = chooser;
119 		
120         RemovableURISelectionPane comp = null;
121         
122         if (page != null) {
123             comp = new RemovableURISelectionPane(page.getProjectView().getFieldManager(), listModel, chooser, false, labelWidth, resultEnabled, parameters);
124         } else {
125             comp = new RemovableURISelectionPane(null, listModel, chooser, false, labelWidth, resultEnabled, parameters);
126         }
127 
128         for (OverviewNode node : comp.getNodes()) {
129             nodes.add(node);
130         }
131 
132         uriSelectors.add( comp);
133 		urisPanel.add( comp, FormLayout.FULL_FILL);
134 		
135 		addButton = new JButton( "Specify another URI");
136 		addButton.addActionListener( new ActionListener() {
137 			public void actionPerformed( ActionEvent e) {
138 				addURISelector(null, null, null);
139 			}
140 		});
141 		
142 		JLabel label = null;
143         if (resultEnabled) {
144             label = new JLabel( "Result:");
145         } else {
146             label = new JLabel( "URI:");
147         }
148         
149         if ( labelWidth != -1) {
150             label.setPreferredSize(new Dimension( labelWidth, label.getPreferredSize().height));
151         } else {
152             label.setPreferredSize(label.getPreferredSize());
153         }
154 
155         label.setText( "");
156 
157         JPanel addPanel = new JPanel( new FlowLayout( FlowLayout.LEFT, 5, 0));
158 		addPanel.add(label);
159 		addPanel.add(addButton);
160 		
161 		add(addPanel, BorderLayout.SOUTH);
162 		add(urisPanel, BorderLayout.CENTER);
163 	}
164 	
165 	private void addURISelector(URI sourceURI, URI resultURI, List<Parameter> map) {
166 		RemovableURISelectionPane comp = null;
167         
168         if (page != null) {
169             comp = new RemovableURISelectionPane(page.getProjectView().getFieldManager(), listModel, chooser, true, labelWidth, resultEnabled, parameters);
170         } else {
171             comp = new RemovableURISelectionPane(null, listModel, chooser, true, labelWidth, resultEnabled, parameters);
172         }
173 
174         comp.setURI(sourceURI);
175 
176         if(parameters) {
177             comp.setParameters(map);
178         }
179         
180         if (resultEnabled) {
181             comp.setResultURI(resultURI);
182         }
183 
184         add(comp);
185 	}
186 	
187     private void add(RemovableURISelectionPane comp) {
188         comp.addRemoveActionListener( this);
189                 
190         for (OverviewNode node : comp.getNodes()) {
191             nodes.add(node);
192 
193             if (page != null) {
194                 ((OverviewTreeModel)page.getParentNode()).nodeInserted(node);
195                 page.getProjectView().getOverviewPanel().expandNode(node);
196             }
197         }
198         
199         uriSelectors.add( comp);
200         urisPanel.add( comp, FormLayout.FULL_FILL);
201 
202         if (page != null) {
203             page.getProjectView().getUndoManager().addEdit(new UndoableAddURISelectionPaneEdit(page, comp));
204         }
205 
206         revalidate();
207         repaint();
208     }
209     
210     public int getButtonWidth() {
211         return uriSelectors.get(0).getButtonWidth();
212     }
213 
214     // Remove button pressed
215 	public void actionPerformed( ActionEvent e) {
216         remove((RemovableURISelectionPane)((Component)e.getSource()).getParent().getParent());
217 	}
218     
219     private void remove(RemovableURISelectionPane comp) {
220         comp.removeRemoveActionListener(this);
221         
222         urisPanel.remove(comp);
223         uriSelectors.remove(comp);
224         
225         if (page != null) {
226             page.getProjectView().getOverviewPanel().selectNode(page);
227         }
228 
229         for (OverviewNode node : comp.getNodes()) {
230             if (page != null) {
231                 ((OverviewTreeModel)page.getParentNode()).nodeRemoved(node);
232             }
233             
234             nodes.remove(node);
235         }
236         
237         if (page != null) {
238             page.getProjectView().getUndoManager().addEdit(new UndoableRemoveURISelectionPaneEdit(page, comp));
239         }
240         
241         revalidate();
242         repaint();
243     }
244 	
245     /***
246      * Removes all extra URI selectors, allowing undo afterwards.
247      */
248     public void removeAllURIs() {
249         for ( int i = uriSelectors.size()-1; i > 0; i--) { 
250             remove(uriSelectors.get(i));
251         }
252 
253         uriSelectors.get(0).setURI(null);
254         
255         if (resultEnabled) {
256             uriSelectors.get(0).setResultURI(null);
257         }
258     }
259 
260     public void reset() {
261 		for ( int i = uriSelectors.size()-1; i > 0; i--) { 
262 			RemovableURISelectionPane comp = uriSelectors.get( i);
263 			comp.removeRemoveActionListener( this);
264 
265 			urisPanel.remove( comp);
266 			uriSelectors.remove( i);
267 		}
268 		
269         uriSelectors.get(0).setURI(null);
270 
271         if (resultEnabled) {
272             uriSelectors.get(0).setResultURI(null);
273         }
274 
275 		revalidate();
276 		repaint();
277 	}
278 
279     public ArrayList<OverviewNode> getNodes() {
280         return nodes;
281     }
282 
283 	public void setURIs(URI base, List uris) {
284         reset();
285         
286 		if ( uris != null) {
287 			for ( int i = 0; i < uris.size(); i++) {
288                 int selector = i;
289 				Document element = (Document)uris.get(i);
290 				URI sourceURI = URIUtils.composeURI(base, element.getSrc());
291                 URI resultURI = null;
292                 List<Parameter> params = null;
293                 
294                 if (resultEnabled) {
295                     selector = i / 2;
296                     i++;
297 
298                     element = (Document)uris.get(i);
299                     resultURI = URIUtils.composeURI(base, element.getSrc());
300                 }
301                 
302                 if (element instanceof ParameterisedDocument) {
303                     params = ((ParameterisedDocument)element).getParameter();
304                 }
305 			
306 				RemovableURISelectionPane comp = null;
307                 if (uriSelectors.size() > selector) {
308                     comp = uriSelectors.get(selector);
309                 }
310 				
311                 if (comp == null) {
312 					addURISelector(sourceURI, resultURI, params);	
313 				} else {
314 					comp.setURI(sourceURI);
315                     comp.setParameters(params);
316                     
317                     if (resultEnabled) {
318                         comp.setResultURI(resultURI);
319                     }
320 				}
321 			}
322 		}
323 	}
324 
325     public List<Document> getURIs(URI base) { 
326 		List<Document> uris = new ArrayList<Document>( uriSelectors.size());
327 
328 		for ( int i = 0; i < uriSelectors.size(); i++) {
329             URI sourceURI = uriSelectors.get(i).getURI(base);
330             URI resultURI = null;
331 
332             if (resultEnabled) {
333                 resultURI = uriSelectors.get(i).getResultURI(base);
334 
335                 if (resultURI != null || sourceURI != null) {
336                     Document source = null;
337                     
338                     if (parameters) {
339                         source = new ParameterisedSource();
340                         ((ParameterisedSource)source).getParameter().addAll(uriSelectors.get(i).getParameters());
341                     } else {
342                         source = new Source();
343                     }
344                     
345                     if (sourceURI != null) {
346                         source.setSrc(sourceURI.toString());
347                     }
348                     
349                     uris.add(source);
350 
351                     Result result = new Result();
352                     
353                     if (resultURI != null) {
354                         result.setSrc(resultURI.toString());
355                     }
356                     
357                     uris.add(result);
358                 }
359             } else if (sourceURI != null) {
360                 Document source = null;
361 
362                 if (parameters) {
363                     source = new ParameterisedSource();
364                     ((ParameterisedSource)source).getParameter().addAll(uriSelectors.get(i).getParameters());
365                 } else {
366                     source = new Source();
367                 }
368 
369                 source.setSrc(sourceURI.toString());
370                 uris.add(source);
371             }
372 		}
373 		
374 		return uris;
375 	}
376     
377     public void dispose() {
378         for (RemovableURISelectionPane selector : uriSelectors) {
379             selector.removeRemoveActionListener( this);
380             selector.dispose();
381         }
382     }
383     
384     public void setEnabled(boolean enabled) {
385         super.setEnabled(enabled);
386 
387         addButton.setEnabled(enabled);
388         
389         for (RemovableURISelectionPane selector : uriSelectors) {
390             selector.setEnabled(enabled);
391         }
392     }
393 
394 	public class RemovableURISelectionPane extends JPanel {
395 		private static final long serialVersionUID = 5536820475944263033L;
396         private JButton removeButton = null;
397         private OverviewNode[] nodes = null;
398 		private URISelectionPane inputSelectionPane = null;
399         private URISelectionPane resultSelectionPane = null;
400         private FieldManager fieldManager = null;
401 		
402 		public RemovableURISelectionPane( FieldManager fieldManager, HistoryListModel listModel, JFileChooser chooser, boolean remove, int labelWidth, boolean resultEnabled, boolean parameters) {
403 			super(new BorderLayout( 0, 2));
404 			
405             JPanel inputPanel = new JPanel(new BorderLayout( 10, 0));
406             String inputLabel = "URI:";
407             
408             if (resultEnabled) {
409                 JLabel label = new JLabel("Source:");
410                 labelWidth = Math.max(label.getPreferredSize().width, labelWidth);
411                 inputLabel = "Source:";
412             }
413             
414             this.fieldManager = fieldManager;
415             
416             if (page != null) {
417                 inputSelectionPane = new URISelectionPane(page, page.getProjectView().getUndoManager(), inputLabel, chooser, labelWidth, new HistoryComboBoxModel(listModel), parameters);
418             } else {
419                 inputSelectionPane = new URISelectionPane(null, null, inputLabel, chooser, labelWidth, new HistoryComboBoxModel(listModel), parameters);
420             }
421 
422             if (fieldManager != null) {
423                 fieldManager.addField( inputSelectionPane.getURIField());
424             }
425 
426             inputPanel.add( inputSelectionPane, BorderLayout.CENTER);
427 
428 			removeButton = new BrowseButton( REMOVE_ICON);
429 			
430 			if ( !remove) {
431 				JLabel label = new JLabel();
432 				label.setPreferredSize( removeButton.getPreferredSize());
433                 inputPanel.add( label, BorderLayout.EAST);
434 			} else {
435 				inputPanel.add( removeButton, BorderLayout.EAST);
436 			}
437             
438             add(inputPanel, BorderLayout.NORTH);
439             
440             if (resultEnabled) {
441                 JPanel outputPanel = new JPanel(new BorderLayout( 10, 0));
442 
443                 if (page != null) {
444                     resultSelectionPane = new URISelectionPane(page, page.getProjectView().getUndoManager(), "Result:", chooser, labelWidth, new HistoryComboBoxModel(listModel), parameters);
445                 } else {
446                     resultSelectionPane = new URISelectionPane(null, null, "Result:", chooser, labelWidth, new HistoryComboBoxModel(listModel), parameters);
447                 }
448     
449                 if (fieldManager != null) {
450                     fieldManager.addField(resultSelectionPane.getURIField());
451                 }
452     
453                 outputPanel.add(resultSelectionPane, BorderLayout.CENTER);
454     
455                 JLabel label = new JLabel();
456                 label.setPreferredSize(removeButton.getPreferredSize());
457                 outputPanel.add(label, BorderLayout.EAST);
458 
459                 add(outputPanel, BorderLayout.SOUTH);
460                 
461                 nodes = new OverviewNode[2];
462                 nodes[0] = new URISelectionNode(parentNode, inputSelectionPane, "source");
463                 nodes[1] = new URISelectionNode(parentNode, resultSelectionPane, "result");
464             } else {
465                 nodes = new OverviewNode[1];
466                 nodes[0] = new URISelectionNode(parentNode, inputSelectionPane, "uri");
467             }
468 		}
469         
470         public boolean hasResult() {
471             return resultSelectionPane != null;
472         }
473 		
474 		public URI getURI(URI base) {
475             return URIUtils.getRelativeURI( base, inputSelectionPane.getURI());
476 		}
477 		
478 		public void setURI( URI uri) {
479 			inputSelectionPane.setURI( uri);
480 		}
481 
482         public List<Parameter> getParameters() {
483             return inputSelectionPane.getParameters();
484         }
485         
486         public void setParameters(List<Parameter> parameters) {
487             inputSelectionPane.setParameters(parameters);
488 
489             for (OverviewNode node : nodes) {
490                 ((URISelectionNode)node).updateParameters();
491             }
492         }
493 
494         public URI getResultURI(URI base) {
495             return URIUtils.getRelativeURI( base, resultSelectionPane.getURI());
496         }
497         
498         public void setResultURI(URI uri) {
499             resultSelectionPane.setURI( uri);
500         }
501 
502         public void addRemoveActionListener( ActionListener listener) {
503 			removeButton.addActionListener( listener);
504 		}
505 
506 		public void removeRemoveActionListener( ActionListener listener) {
507 			removeButton.removeActionListener( listener);
508 		}
509         
510         public void setEnabled( boolean enabled) {
511             super.setEnabled( enabled);
512             inputSelectionPane.setEnabled( enabled);
513             removeButton.setEnabled( enabled);
514 
515             if (resultSelectionPane != null) { 
516                 resultSelectionPane.setEnabled( enabled);
517             }
518         }
519         
520         public void dispose() {
521             if (fieldManager != null) {
522                 fieldManager.removeField( inputSelectionPane.getURIField());
523             }
524             
525             inputSelectionPane.dispose();
526 
527             if (resultSelectionPane != null) { 
528                 resultSelectionPane.dispose();
529             }
530         }
531 
532         public int getButtonWidth() {
533             return removeButton.getPreferredSize().width + inputSelectionPane.getButtonWidth();
534         }
535         
536         public OverviewNode[] getNodes() {
537             return nodes;
538         }
539 	}
540     
541     public class UndoableAddURISelectionPaneEdit extends AbstractUndoableEdit {
542         private static final long serialVersionUID = 8615885869967750791L;
543 
544         private Page page = null;
545         private RemovableURISelectionPane comp = null;
546         
547         public UndoableAddURISelectionPaneEdit(Page page, RemovableURISelectionPane pane) {
548             super();
549             
550             this.page = page;
551             this.comp = pane;
552         }
553 
554         public void undo() {
555             super.undo();
556             
557             remove(comp);
558 
559             page.getProjectView().getOverviewPanel().selectNode(page);
560         }
561 
562         public void redo() {
563             super.redo();
564 
565             add(comp);
566 
567             page.getProjectView().getOverviewPanel().selectNode(page);
568         }
569     }    
570 
571     public class UndoableRemoveURISelectionPaneEdit extends AbstractUndoableEdit {
572         private static final long serialVersionUID = 8615885869967750791L;
573 
574         private Page page = null;
575         private RemovableURISelectionPane comp = null;
576         
577         public UndoableRemoveURISelectionPaneEdit(Page page, RemovableURISelectionPane pane) {
578             super();
579             
580             this.page = page;
581             this.comp = pane;
582         }
583 
584         public void undo() {
585             super.undo();
586             
587             add(comp);
588 
589             page.getProjectView().getOverviewPanel().selectNode(page);
590         }
591 
592         public void redo() {
593             super.redo();
594 
595             remove(comp);
596 
597             page.getProjectView().getOverviewPanel().selectNode(page);
598         }
599     }    
600 }