001: /*
002: * Beryl - A web platform based on XML, XSLT and Java
003: * This file is part of the Beryl XML GUI
004: *
005: * Copyright (C) 2004 Wenzel Jakob <wazlaf@tigris.org>
006: * Simon Epstein <anyone@simondo.com>
007: *
008: * This program is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Lesser General Public
010: * License as published by the Free Software Foundation; either
011: * version 2.1 of the License, or (at your option) any later version.
012:
013: * This program is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public
019: * License along with this program; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-3107 USA
021: */
022:
023: package org.beryl.gui.builder;
024:
025: import java.io.File;
026: import java.io.FileOutputStream;
027: import java.io.IOException;
028: import java.io.PrintWriter;
029: import java.util.Locale;
030: import java.util.Properties;
031:
032: import javax.help.HelpSet;
033: import javax.xml.parsers.DocumentBuilderFactory;
034: import javax.xml.parsers.ParserConfigurationException;
035:
036: import org.beryl.gui.Controller;
037: import org.beryl.gui.DialogUtils;
038: import org.beryl.gui.GUIEvent;
039: import org.beryl.gui.GUIException;
040: import org.beryl.gui.GUIUtils;
041: import org.beryl.gui.ImageIconFactory;
042: import org.beryl.gui.InternationalizationManager;
043: import org.beryl.gui.MessageDialog;
044: import org.beryl.gui.Widget;
045: import org.beryl.gui.XMLUtils;
046: import org.beryl.gui.widgets.Frame;
047: import org.w3c.dom.Document;
048: import org.w3c.dom.Element;
049:
050: public class Builder extends Controller {
051: private static DocumentBuilderFactory dbf = DocumentBuilderFactory
052: .newInstance();
053:
054: /**
055: * Main window
056: */
057: private Frame frame = null;
058:
059: /**
060: * Widget tree window
061: */
062: private WidgetTree widgetTree = null;
063:
064: /**
065: * Currently open file
066: */
067: private File file = null;
068:
069: /**
070: * DOM representation of the XML file
071: */
072: private Document document = null;
073:
074: /**
075: * Indicates whether there have been changes since the last save
076: */
077: private static boolean modified = false;
078:
079: /**
080: * Custom internationalization properties
081: */
082: private Properties intlProps = null;
083:
084: /**
085: * Internationalization editor
086: */
087: private InternationalizationEditor intlEditor = null;
088:
089: /**
090: * Look and feel chooser
091: */
092: private LookAndFeelChooser lnfChooser = null;
093:
094: /**
095: * Custom internationalization source
096: */
097: private class InternationalizationSource implements
098: InternationalizationManager.InternationalizationSource {
099: public String getString(String identifier) {
100: return intlProps.getProperty(identifier);
101: }
102: };
103:
104: /**
105: * Constructor
106: * @throws GUIException
107: */
108: public Builder() throws GUIException {
109: frame = (Frame) constructFrame("Builder");
110: widgetTree = new WidgetTree(this );
111: intlProps = new Properties();
112: InternationalizationManager
113: .addInternationalizationSource(new InternationalizationSource());
114: frame.show();
115: doNew();
116: }
117:
118: /**
119: * Create an empty document
120: * @throws GUIException
121: */
122: private void doNew() throws GUIException {
123: try {
124: document = dbf.newDocumentBuilder().newDocument();
125: Element uiElement = document.createElement("UI");
126: uiElement.setAttribute("version", "1.0");
127: document.appendChild(uiElement);
128: } catch (ParserConfigurationException e) {
129: throw new GUIException(
130: "Error while initializing XML parser", e);
131: }
132: modified = false;
133: doRefresh();
134: }
135:
136: /**
137: * Save the document to disk
138: * @throws GUIException
139: */
140: private void doSave() throws GUIException {
141: if (file == null) {
142: doSaveAs();
143: } else {
144: try {
145: PrintWriter writer = new PrintWriter(
146: new FileOutputStream(file));
147: writer.println(XMLUtils.serializeXML(document));
148: writer.close();
149: } catch (IOException e) {
150: throw new GUIException("Could not create file", e);
151: }
152: modified = false;
153: }
154: }
155:
156: /**
157: * Popup a save as dialog
158: * @throws GUIException
159: */
160: private void doSaveAs() throws GUIException {
161: File newFile = DialogUtils.showSaveFileDialog(frame, "xml");
162: if (newFile != null) {
163: file = newFile;
164: doSave();
165: }
166: }
167:
168: /**
169: * Generate a skeleton
170: */
171: private void doSkeleton() throws GUIException {
172: new SkeletonDialog(frame, document);
173: }
174:
175: /**
176: * Popup an open dialog
177: * @throws GUIException
178: */
179: private void doOpen() throws GUIException {
180: File newFile = DialogUtils.showOpenFileDialog(frame, "xml");
181: if (newFile != null) {
182: try {
183: document = dbf.newDocumentBuilder().parse(newFile);
184: } catch (Exception e) {
185: throw new GUIException("Could not open file", e);
186: }
187: file = newFile;
188: modified = false;
189: doRefresh();
190: }
191: }
192:
193: private boolean doAskSaveCancel() throws GUIException {
194: if (modified) {
195: switch (DialogUtils.showYesNoCancelDialog(frame,
196: getString("builder.save.title"),
197: getString("builder.save.label"))) {
198: case DialogUtils.RESULT_YES:
199: doSave();
200: return true;
201: case DialogUtils.RESULT_NO:
202: return true;
203: case DialogUtils.RESULT_CANCEL:
204: return false;
205: }
206: }
207: return true;
208: }
209:
210: /**
211: * Mark the document as modified
212: */
213: public static void markModified() {
214: modified = true;
215: }
216:
217: /**
218: * Refresh the views
219: */
220: private void doRefresh() throws GUIException {
221: widgetTree.refresh(document);
222: }
223:
224: public void eventOccured(GUIEvent event) {
225: String name = event.getName();
226: try {
227: if (name.equals("quit")) {
228: if (doAskSaveCancel()
229: && (intlEditor == null || intlEditor
230: .doAskSaveCancel(frame)))
231: System.exit(0);
232: } else if (name.equals("open")) {
233: if (doAskSaveCancel())
234: doOpen();
235: } else if (name.equals("save")) {
236: doSave();
237: } else if (name.equals("skeleton")) {
238: doSkeleton();
239: } else if (name.equals("saveAs")) {
240: doSaveAs();
241: } else if (name.equals("new")) {
242: if (doAskSaveCancel())
243: doNew();
244: } else if (name.equals("lookandfeel")) {
245: if (lnfChooser == null || !lnfChooser.isVisible())
246: lnfChooser = new LookAndFeelChooser();
247: } else if (name.equals("i18n")) {
248: if (intlEditor == null || !intlEditor.isVisible())
249: intlEditor = new InternationalizationEditor(
250: widgetTree, intlProps);
251: } else if (name.equals("help")) {
252: showHelp("preface");
253: } else if (name.equals("about")) {
254: new About(frame);
255: } else if (name.startsWith("insert:")) {
256: widgetTree.doInsert(name.substring(7));
257: }
258: } catch (GUIException e) {
259: new MessageDialog(e);
260: }
261: }
262:
263: /**
264: * Initialize log4j and start the GUI builder
265: * @param args Command-line parameters are ignored
266: */
267: public static void main(String args[]) {
268: try {
269: Locale locale = Locale.US;
270:
271: if (Locale.getDefault().getLanguage().equals("de"))
272: locale = new Locale("de", "DE");
273:
274: ClassLoader cl = Builder.class.getClassLoader();
275: GUIUtils.defaultInitialization(locale);
276:
277: InternationalizationManager
278: .addLanguageFile("resources/builder/builder");
279: ImageIconFactory.addSearchPath("resources/builder/icons");
280: Widget.setHelpSet(new HelpSet(cl, HelpSet.findHelpSet(cl,
281: "resources/builder/help/builder."
282: + locale.toString() + ".hs")));
283: new Builder();
284: } catch (Exception e) {
285: new MessageDialog(e);
286: }
287: }
288: }
|