1 /*-
2  * Copyright (C) 2008 Erik Larsson
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 package org.catacombae.hfsexplorer.testcode.editgpt;
19 
20 import java.awt.event.ActionEvent;
21 import java.awt.event.ActionListener;
22 import java.util.LinkedList;
23 import java.util.List;
24 import javax.swing.Box;
25 import javax.swing.JComponent;
26 import javax.swing.JOptionPane;
27 import org.catacombae.csjc.structelements.Array;
28 import org.catacombae.csjc.structelements.Dictionary;
29 import org.catacombae.csjc.structelements.StringRepresentableField;
30 import org.catacombae.csjc.structelements.StructElement;
31 
32 /**
33  * @author <a href="http://www.catacombae.org/" target="_top">Erik Larsson</a>
34  */
35 public class ContainerPanel extends javax.swing.JPanel {
36     private LinkedList<ContainerPanel> subPanels = new LinkedList<ContainerPanel>();
37     private LinkedList<EditStringValuePanel> fields = new LinkedList<EditStringValuePanel>();
38 
ContainerPanel()39     public ContainerPanel() {
40         this(null);
41     }
42 
43     /** Creates new form ContainerPanel */
ContainerPanel(String label)44     public ContainerPanel(String label) {
45         initComponents();
46 
47         if(label != null) {
48             descriptionLabel.setText(label);
49             saveButton.setVisible(false);
50         }
51         else {
52             descriptionLabel.setVisible(false);
53             saveButton.addActionListener(new ActionListener() {
54                 public void actionPerformed(ActionEvent evt) {
55                     actionSave();
56                 }
57             });
58         }
59     }
60 
61     /** This method is called from within the constructor to
62      * initialize the form.
63      * WARNING: Do NOT modify this code. The content of this method is
64      * always regenerated by the Form Editor.
65      */
66     @SuppressWarnings("unchecked")
67     // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
initComponents()68     private void initComponents() {
69 
70         contentsPanel = new javax.swing.JPanel();
71         descriptionLabel = new javax.swing.JLabel();
72         saveButton = new javax.swing.JButton();
73 
74         contentsPanel.setLayout(new javax.swing.BoxLayout(contentsPanel, javax.swing.BoxLayout.PAGE_AXIS));
75 
76         descriptionLabel.setText("jLabel1");
77 
78         saveButton.setText("Save");
79 
80         org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
81         this.setLayout(layout);
82         layout.setHorizontalGroup(
83             layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
84             .add(layout.createSequentialGroup()
85                 .addContainerGap()
86                 .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
87                     .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
88                         .add(10, 10, 10)
89                         .add(contentsPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 219, Short.MAX_VALUE))
90                     .add(layout.createSequentialGroup()
91                         .add(descriptionLabel)
92                         .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 109, Short.MAX_VALUE)
93                         .add(saveButton)))
94                 .addContainerGap())
95         );
96         layout.setVerticalGroup(
97             layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
98             .add(layout.createSequentialGroup()
99                 .addContainerGap()
100                 .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
101                     .add(descriptionLabel)
102                     .add(saveButton))
103                 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
104                 .add(contentsPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 107, Short.MAX_VALUE)
105                 .addContainerGap())
106         );
107     }// </editor-fold>//GEN-END:initComponents
108 
setFields(Dictionary rootDict)109     public void setFields(Dictionary rootDict) {
110         contentsPanel.removeAll();
111         String[] keys = rootDict.getKeys();
112 
113         for(String key : keys) {
114             System.err.println("setFields processing key \"" + key + "\"...");
115             StructElement curElem = rootDict.getElement(key);
116             System.err.println("  curElem = " + curElem);
117             if(curElem instanceof StringRepresentableField) {
118                 StringRepresentableField curField = (StringRepresentableField)curElem;
119                 EditStringValuePanel panel = new EditStringValuePanel();
120                 panel.setDecription(key + " (" + curField.getTypeName() + ")");
121                 panel.setValue(curField.getValueAsString());
122                 panel.setUserData(curField);
123                 System.err.println("  (1)adding " + panel + " to containerpanel");
124                 addComponent(panel);
125                 fields.add(panel);
126             }
127             else if(curElem instanceof Dictionary) {
128                 Dictionary curDict = (Dictionary)curElem;
129                 ContainerPanel panel = new ContainerPanel(key + " (" + curDict.getTypeName() + ")");
130                 panel.setFields(curDict);
131                 System.err.println("  (2)adding " + panel + " to containerpanel");
132                 addComponent(panel);
133                 subPanels.add(panel);
134             }
135             else if(curElem instanceof Array) {
136                 Array curArray = (Array)curElem;
137                 ContainerPanel panel = new ContainerPanel(key + " (" + curArray.getTypeName() + ")");
138                 panel.setFields(curArray);
139                 System.err.println("  (2)adding " + panel + " to containerpanel");
140                 addComponent(panel);
141                 subPanels.add(panel);
142             }
143             else
144                 throw new RuntimeException("Unknown StructElement type: " + curElem.getClass());
145         }
146         contentsPanel.add(Box.createVerticalGlue());
147     }
148 
setFields(Array rootArray)149     public void setFields(Array rootArray) {
150         contentsPanel.removeAll();
151         StructElement[] elements = rootArray.getElements();
152 
153         for(int i = 0; i < elements.length; ++i) {
154             StructElement curElem = elements[i];
155             System.err.println("setFields processing array element...");
156             System.err.println("  curElem = " + curElem);
157             if(curElem instanceof StringRepresentableField) {
158                 StringRepresentableField curField = (StringRepresentableField)curElem;
159                 EditStringValuePanel panel = new EditStringValuePanel();
160                 panel.setDecription("[" + i + "] (" + curField.getTypeName() + ")");
161                 panel.setValue(curField.getValueAsString());
162                 panel.setUserData(curField);
163                 System.err.println("  (1)adding " + panel + " to containerpanel");
164                 addComponent(panel);
165             }
166             else if(curElem instanceof Dictionary) {
167                 Dictionary curDict = (Dictionary)curElem;
168                 ContainerPanel panel = new ContainerPanel("[" + i + "] (" + curDict.getTypeName() + ")");
169                 panel.setFields(curDict);
170                 System.err.println("  (2)adding " + panel + " to containerpanel");
171                 addComponent(panel);
172             }
173             else if(curElem instanceof Array) {
174                 Array curArray = (Array)curElem;
175                 ContainerPanel panel = new ContainerPanel("[" + i + "] (" + curArray.getTypeName() + ")");
176                 panel.setFields(curArray);
177                 System.err.println("  (3)adding " + panel + " to containerpanel");
178                 addComponent(panel);
179             }
180             else
181                 throw new RuntimeException("Unknown StructElement type: " + curElem.getClass());
182         }
183         contentsPanel.add(Box.createVerticalGlue());
184     }
185 
186 
actionSave()187     private void actionSave() {
188         // Gather all the modified components
189         List<EditStringValuePanel> modifiedFields = getModifiedFields();
190         if(modifiedFields.size() == 0) {
191             JOptionPane.showMessageDialog(this, "Nothing to save.", "Information",
192                     JOptionPane.INFORMATION_MESSAGE);
193             return;
194         }
195 
196         // Validate their data
197         StringBuilder messageBuilder = new StringBuilder();
198         for(EditStringValuePanel vp : modifiedFields) {
199             StringRepresentableField field = vp.getUserData();
200             String validateRes = field.validateStringValue(vp.getValue());
201             if(validateRes != null) {
202                 messageBuilder.append(vp.getDescription()).append(": ").append(vp.getValue());
203                 messageBuilder.append(" [").append(validateRes).append("]\n");
204             }
205         }
206 
207         if(messageBuilder.length() != 0) {
208             JOptionPane.showMessageDialog(this, "The following fields failed to validate:\n\n" +
209                     messageBuilder.toString(), "Error", JOptionPane.ERROR_MESSAGE);
210         }
211         else {
212             messageBuilder.append("The following modifications were made:\n\n");
213             for(EditStringValuePanel vp : modifiedFields) {
214                 messageBuilder.append(vp.getDescription()).append(": \"").append(vp.getValue())
215                         .append("\"\n");
216             }
217             messageBuilder.append("\nCarry on with save?");
218 
219             JOptionPane.showConfirmDialog(this, messageBuilder.toString(), "Confirm save",
220                     JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
221         }
222     }
223 
getModifiedFields()224     private List<EditStringValuePanel> getModifiedFields() {
225         LinkedList<EditStringValuePanel> tmpList = new LinkedList<EditStringValuePanel>();
226         for(EditStringValuePanel field : fields) {
227             if(field.isModified())
228                 tmpList.add(field);
229         }
230 
231         for(ContainerPanel cp : subPanels)
232             tmpList.addAll(cp.getModifiedFields());
233 
234         return tmpList;
235     }
236 
addComponent(JComponent jc)237     private void addComponent(JComponent jc) {
238 
239         contentsPanel.add(jc);
240 
241     }
242 
243     // Variables declaration - do not modify//GEN-BEGIN:variables
244     private javax.swing.JPanel contentsPanel;
245     private javax.swing.JLabel descriptionLabel;
246     private javax.swing.JButton saveButton;
247     // End of variables declaration//GEN-END:variables
248 
249 }
250