001    // This file is part of AceWiki.
002    // Copyright 2008-2012, AceWiki developers.
003    // 
004    // AceWiki is free software: you can redistribute it and/or modify it under the terms of the GNU
005    // Lesser General Public License as published by the Free Software Foundation, either version 3 of
006    // the License, or (at your option) any later version.
007    // 
008    // AceWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009    // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
010    // Lesser General Public License for more details.
011    // 
012    // You should have received a copy of the GNU Lesser General Public License along with AceWiki. If
013    // not, see http://www.gnu.org/licenses/.
014    
015    package ch.uzh.ifi.attempto.preditor;
016    
017    import java.util.ArrayList;
018    import java.util.List;
019    
020    import nextapp.echo.app.Alignment;
021    import nextapp.echo.app.ApplicationInstance;
022    import nextapp.echo.app.Border;
023    import nextapp.echo.app.Color;
024    import nextapp.echo.app.Column;
025    import nextapp.echo.app.Component;
026    import nextapp.echo.app.ContentPane;
027    import nextapp.echo.app.Extent;
028    import nextapp.echo.app.Font;
029    import nextapp.echo.app.Grid;
030    import nextapp.echo.app.Insets;
031    import nextapp.echo.app.Row;
032    import nextapp.echo.app.WindowPane;
033    import nextapp.echo.app.event.ActionEvent;
034    import nextapp.echo.app.event.ActionListener;
035    import nextapp.echo.app.layout.GridLayoutData;
036    import ch.uzh.ifi.attempto.echocomp.GeneralButton;
037    import ch.uzh.ifi.attempto.echocomp.Label;
038    import ch.uzh.ifi.attempto.echocomp.SolidLabel;
039    import ch.uzh.ifi.attempto.echocomp.TextField;
040    
041    /**
042     * This class represents a form that appears within a tab of the word editor window. Such a form
043     * contains the form elements for a certain class of words.
044     * 
045     * @author Tobias Kuhn
046     */
047    public class WordEditorForm extends ContentPane implements ActionListener {
048    
049            private static final long serialVersionUID = 5886665203518065212L;
050            
051            private ActionListener actionListener;
052            private WindowPane parentWindow;
053            private Row buttonBar;
054            private String title = "";
055            private Column column;
056            private Row explanationRow;
057            private List<Component> formElements = new ArrayList<Component>();
058            private List<Component> requiredFormElements = new ArrayList<Component>();
059            
060            /**
061             * Creates a new word editor form.
062             * 
063             * @param parentWindow The parent window.
064             * @param actionListener The action-listener.
065             */
066            public WordEditorForm(WindowPane parentWindow, ActionListener actionListener) {
067                    this.parentWindow = parentWindow;
068                    this.actionListener = actionListener;
069                    
070                    Column borderCol = new Column();
071                    borderCol.setBorder(new Border(1, Color.BLACK, Border.STYLE_INSET));
072                    
073                    Grid grid = new Grid(1);
074                    grid.setRowHeight(0, new Extent(parentWindow.getHeight().getValue()-160));
075                    grid.setRowHeight(1, new Extent(30));
076                    
077                    column = new Column();
078                    column.setInsets(new Insets(10, 20, 0, 0));
079                    column.setCellSpacing(new Extent(10));
080                    GridLayoutData gridLayout = new GridLayoutData();
081                    gridLayout.setAlignment(new Alignment(Alignment.LEFT, Alignment.TOP));
082                    column.setLayoutData(gridLayout);
083                    grid.add(column);
084                    
085                    explanationRow = new Row();
086                    column.add(explanationRow);
087                    
088                    Row footerRow = new Row();
089                    footerRow.setInsets(new Insets(10, 0, 0, 0));
090                    footerRow.add(new Label("* required field", Font.ITALIC, 11));
091                    grid.add(footerRow);
092                    
093                    buttonBar = new Row();
094                    buttonBar.setAlignment(new Alignment(Alignment.RIGHT, Alignment.CENTER));
095                    buttonBar.setInsets(new Insets(10, 10, 10, 10));
096                    buttonBar.setCellSpacing(new Extent(5));
097                    grid.add(buttonBar);
098                    
099                    addButton("OK");
100                    addButton("Cancel");
101                    
102                    borderCol.add(grid);
103                    add(borderCol);
104            }
105            
106            /**
107             * Creates a new word editor form.
108             * 
109             * @param title The title of the word editor form.
110             * @param parentWindow The parent window.
111             * @param actionListener The action-listener.
112             */
113            public WordEditorForm(String title, WindowPane parentWindow, ActionListener actionListener) {
114                    this(parentWindow, actionListener);
115                    setTitle(title);
116            }
117            
118            /**
119             * Sets the title of this form.
120             * 
121             * @param title The title.
122             */
123            public void setTitle(String title) {
124                    this.title = title;
125            }
126            
127            /**
128             * Returns the title of the word editor form.
129             * 
130             * @return The title.
131             */
132            public String getTitle() {
133                    return title;
134            }
135            
136            /**
137             * Return the parent window of this form.
138             * 
139             * @return The parent window.
140             */
141            public WindowPane getParentWindow() {
142                    return parentWindow;
143            }
144            
145            /**
146             * Returns the action-listener.
147             * 
148             * @return The action-listener.
149             */
150            public ActionListener getActionListener() {
151                    return actionListener;
152            }
153            
154            /**
155             * Adds a button to the button bar.
156             * 
157             * @param buttonText The text of the button.
158             */
159            public void addButton(String buttonText) {
160                    buttonBar.add(new GeneralButton(buttonText, 70, this));
161            }
162            
163            /**
164             * Removes all existing buttons and adds the given buttons to the button bar.
165             * 
166             * @param buttonTexts The texts for the buttons.
167             */
168            public void setButtons(String... buttonTexts) {
169                    buttonBar.removeAll();
170                    for (String t : buttonTexts) {
171                            addButton(t);
172                    }
173            }
174            
175            /**
176             * Adds a new row to the form.
177             * 
178             * @param labelText The text for the label shown on the left hand side of the component.
179             * @param formElement The component, i.e. a text field.
180             * @param explanation An explanation text shown under the component.
181             * @param required Defines whether the component should be marked as required.
182             */
183            public void addRow(String labelText, Component formElement, String explanation,
184                            boolean required) {
185                    Grid grid = new Grid(3);
186                    grid.setInsets(new Insets(0, 0, 5, 0));
187                    grid.setColumnWidth(0, new Extent(140));
188                    grid.add(new SolidLabel(labelText, Font.ITALIC));
189                    formElements.add(formElement);
190                    if (formElement instanceof TextField) {
191                            TextField tf = (TextField) formElement;
192                            tf.setWidth(new Extent(parentWindow.getWidth().getValue()-223));
193                            tf.setActionCommand("OK");
194                    }
195                    grid.add(formElement);
196                    if (required) {
197                            requiredFormElements.add(formElement);
198                            grid.add(new Label("*", Font.ITALIC, 11));
199                    } else {
200                            grid.add(new Label());
201                    }
202                    grid.add(new Label());
203                    grid.add(new Label(explanation, Font.ITALIC, 11));
204                    column.add(grid);
205            }
206    
207            /**
208             * Sets the explanation component. The explanation component is shown above the form elements
209             * and should explain how these form elements have to be used.
210             * 
211             * @param comp The graphical component.
212             */
213            public void setExplanationComponent(Component comp) {
214                    explanationRow.removeAll();
215                    explanationRow.add(comp);
216            }
217            
218            /**
219             * Returns all form elements.
220             * 
221             * @return A list of all form elements.
222             */
223            public List<Component> getFormElements() {
224                    return formElements;
225            }
226            
227            /**
228             * Returns all form elements that are marked as required.
229             * 
230             * @return A list of all required form elements.
231             */
232            public List<Component> getRequiredFormElements() {
233                    return requiredFormElements;
234            }
235            
236            /**
237             * Returns the content of all form elements that are text fields.
238             * 
239             * @return A list of the content of all form elements that are text fields.
240             */
241            public List<String> getRequiredTextFieldContents() {
242                    List<String> textContents = new ArrayList<String>();
243                    for (Component comp : requiredFormElements) {
244                            if (comp instanceof TextField) {
245                                    textContents.add(((TextField) comp).getText());
246                            }
247                    }
248                    return textContents;
249            }
250            
251            /**
252             * This method sets the focus on the first enabled text field of this form.
253             */
254            protected void doFocus() {
255                    doFocus(this);
256            }
257            
258            private boolean doFocus(Component c) {
259                    if (c instanceof TextField) {
260                            TextField tf = (TextField) c;
261                            if (tf.isEnabled()) {
262                                    ApplicationInstance.getActive().setFocusedComponent(tf);
263                                    return true;
264                            } else {
265                                    return false;
266                            }
267                    } else {
268                            for (Component child : c.getComponents()) {
269                                    boolean b = doFocus(child);
270                                    if (b) return true;
271                            }
272                    }
273                    return false;
274            }
275            
276            public void actionPerformed(ActionEvent e) {
277                    actionListener.actionPerformed(new ActionEvent(parentWindow, e.getActionCommand()));
278            }
279    
280    }