001: /*
002: * Copyright (C) 2005 Jeff Tassin
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018:
019: package com.jeta.swingbuilder.gui.formmgr;
020:
021: import java.awt.Component;
022: import java.awt.Container;
023: import java.awt.Toolkit;
024: import java.awt.datatransfer.Clipboard;
025: import java.awt.datatransfer.Transferable;
026: import java.io.File;
027: import java.util.Collection;
028: import java.util.Iterator;
029: import java.util.LinkedList;
030: import java.util.TreeSet;
031:
032: import javax.swing.JOptionPane;
033:
034: import com.jeta.forms.gui.common.FormException;
035: import com.jeta.forms.gui.form.FormComponent;
036: import com.jeta.forms.gui.form.GridComponent;
037: import com.jeta.forms.gui.form.GridView;
038: import com.jeta.forms.gui.formmgr.FormManager;
039: import com.jeta.forms.logger.FormsLogger;
040: import com.jeta.forms.project.ProjectManager;
041: import com.jeta.forms.store.memento.FormMemento;
042: import com.jeta.forms.store.memento.StateRequest;
043: import com.jeta.open.gui.utils.JETAToolbox;
044: import com.jeta.open.i18n.I18N;
045: import com.jeta.open.registry.JETARegistry;
046: import com.jeta.open.support.EmptyCollection;
047: import com.jeta.swingbuilder.gui.dnd.FormObjectFlavor;
048: import com.jeta.swingbuilder.gui.editor.FormEditor;
049: import com.jeta.swingbuilder.gui.filechooser.FileChooserConfig;
050: import com.jeta.swingbuilder.gui.filechooser.TSFileChooserFactory;
051: import com.jeta.swingbuilder.gui.filechooser.TSFileFilter;
052:
053: /**
054: * Utility functions for dealing with the FormManager while in design mode.
055: *
056: * @author Jeff Tassin
057: */
058: public class FormManagerDesignUtils {
059:
060: /**
061: * Traverses the container hiearchy and checks if each child component is an
062: * instance of a FormComponent that has the given form id.
063: *
064: * @return true if the given form contains a nested form with the given id.
065: */
066: public static boolean containsForm(Container cc, String formId) {
067: if (cc == null)
068: return false;
069:
070: if (cc instanceof FormComponent) {
071: FormComponent form = (FormComponent) cc;
072: if (formId.equals(form.getId()))
073: return true;
074: } else if (cc instanceof FormSurrogate) {
075: if (containsForm(((FormSurrogate) cc).getForm(), formId))
076: return true;
077: }
078:
079: for (int index = 0; index < cc.getComponentCount(); index++) {
080: Component comp = cc.getComponent(index);
081: if (comp instanceof Container) {
082: if (containsForm((Container) comp, formId))
083: return true;
084: }
085: }
086: return false;
087: }
088:
089: /**
090: * Creates a clone of the given form component. This will also reset the
091: * id's of all the embedded child forms and register the new forms with the
092: * form manager
093: */
094: public static FormComponent clone(FormManager fmgr,
095: FormEditor editor, String newPath) throws FormException {
096: FormComponent fc = editor.getForm();
097: FormMemento memento = fc
098: .getExternalState(StateRequest.SHALLOW_COPY);
099:
100: /**
101: * we must first deactivate all forms in the editor because when we set
102: * the state on the cloned object, any linked forms are added
103: */
104: fmgr.deactivateForms(editor);
105:
106: FormComponent fcopy = FormComponent.create();
107: fcopy.setState(memento);
108: if (newPath != null)
109: fcopy.setAbsolutePath(newPath);
110:
111: return fcopy;
112: }
113:
114: /**
115: * Clears all forms in the given form manager that are not referenced or
116: * contained in any editor.
117: */
118: public static void clearUnreferencedForms() {
119: FormManager fmgr = (FormManager) JETARegistry
120: .lookup(FormManager.COMPONENT_ID);
121: if (fmgr instanceof AbstractFormManager) {
122: TreeSet ref_forms = new TreeSet();
123: ref_forms.addAll(getLinkedFormsFromClipboard());
124: AbstractFormManager afm = (AbstractFormManager) fmgr;
125: EditorManager em = afm.getEditorManager();
126: Collection editors = em.getEditors();
127: Iterator iter = editors.iterator();
128: while (iter.hasNext()) {
129: FormEditor editor = (FormEditor) iter.next();
130: ref_forms.addAll(getNestedForms(fmgr, editor
131: .getTopParent()));
132: ref_forms.add(editor.getTopParent().getId());
133: }
134:
135: Collection forms = fmgr.getForms();
136: LinkedList to_remove = new LinkedList();
137: to_remove.addAll(forms);
138: iter = to_remove.iterator();
139: while (iter.hasNext()) {
140: String fid = (String) iter.next();
141: if (!ref_forms.contains(fid)) {
142: FormsLogger
143: .debug("FormManagerDesignUtils.clearUnreferencedForms removed form: "
144: + fid);
145: fmgr.removeForm(fid);
146: }
147: }
148: }
149: }
150:
151: /**
152: * Recursively deselects all cells
153: */
154: public static void deselectAll(FormComponent form) {
155: if (form == null)
156: return;
157:
158: GridView view = form.getChildView();
159: view.deselectAll();
160: Iterator iter = view.gridIterator();
161: while (iter.hasNext()) {
162: GridComponent gc = (GridComponent) iter.next();
163: gc.setSelected(false);
164: if (gc instanceof FormComponent) {
165: deselectAll((FormComponent) gc);
166: }
167: }
168: }
169:
170: private static int getComponentCount(FormManager fmgr,
171: Container form) {
172: if (form == null)
173: return 0;
174:
175: int totalCount = 0;
176: for (int index = 0; index < form.getComponentCount(); index++) {
177: Component comp = form.getComponent(index);
178: if (comp instanceof Container) {
179: if (comp instanceof FormSurrogate) {
180: totalCount += getComponentCount(fmgr,
181: ((FormSurrogate) comp).getForm());
182: } else {
183: totalCount += getComponentCount(fmgr,
184: (Container) comp);
185: }
186:
187: if (comp instanceof GridComponent) {
188: java.awt.Component bean = ((GridComponent) comp)
189: .getBeanDelegate();
190: if (bean instanceof javax.swing.JComponent) {
191: totalCount++;
192: }
193: }
194: }
195: }
196: return totalCount;
197: }
198:
199: /**
200: * @return the total number of components in the form
201: */
202: public static int getComponentCount(FormComponent form) {
203: FormManager fmgr = (FormManager) JETARegistry
204: .lookup(FormManager.COMPONENT_ID);
205: return getComponentCount(fmgr, form);
206: }
207:
208: /**
209: * Gets the ids of all nested forms contained in this component
210: */
211: public static void getNestedForms(FormManager fmgr,
212: LinkedList list, Container cc) {
213: if (cc == null) {
214: return;
215: }
216:
217: for (int index = 0; index < cc.getComponentCount(); index++) {
218: Component comp = cc.getComponent(index);
219: if (comp instanceof FormComponent
220: || comp instanceof FormSurrogate) {
221: list.add(((GridComponent) comp).getId());
222: }
223:
224: if (comp instanceof FormSurrogate) {
225: getNestedForms(fmgr, list, ((FormSurrogate) comp)
226: .getForm());
227: } else if (comp instanceof Container) {
228: getNestedForms(fmgr, list, (Container) comp);
229: }
230: }
231: }
232:
233: /**
234: * @return the ids (as a Collection of Strings) of all nested forms
235: * contained in this component
236: */
237: public static Collection getNestedForms(FormManager fmgr,
238: FormComponent fc) {
239: LinkedList list = new LinkedList();
240: getNestedForms(fmgr, list, fc);
241: return list;
242: }
243:
244: /**
245: * Get all linked forms that are nested within the given form component.
246: */
247: private static void getLinkedForms(LinkedList list, Container cc) {
248: if (cc == null) {
249: assert (false);
250: return;
251: }
252:
253: if (cc instanceof FormComponent) {
254: FormComponent fc = (FormComponent) cc;
255: if (fc.isLinked())
256: list.add(fc.getId());
257: } else if (cc instanceof FormSurrogate) {
258: FormComponent fc = ((FormSurrogate) cc).getForm();
259: if (fc != null && fc.isLinked())
260: list.add(fc.getId());
261:
262: cc = fc;
263: }
264:
265: for (int index = 0; index < cc.getComponentCount(); index++) {
266: Component comp = cc.getComponent(index);
267: if (comp instanceof Container)
268: getLinkedForms(list, (Container) comp);
269: }
270: }
271:
272: /**
273: * @return a set of all nested linked form ids (String objects) including
274: * the given form that are contained by the given form.
275: */
276: public static Collection getLinkedForms(Container cc) {
277: LinkedList forms = new LinkedList();
278: getLinkedForms(forms, cc);
279: return forms;
280: }
281:
282: public static Component getApplicationFrame() {
283: Object comp = JETARegistry
284: .lookup(JETAToolbox.APPLICATION_FRAME);
285: if (comp instanceof Component)
286: return (Component) comp;
287: else
288: return null;
289: }
290:
291: /**
292: * @return the collection of linked form ids on the clipboard if any.
293: */
294: public static Collection getLinkedFormsFromClipboard() {
295: try {
296: Toolkit kit = Toolkit.getDefaultToolkit();
297: Clipboard clipboard = kit.getSystemClipboard();
298: Transferable transferable = clipboard.getContents(null);
299: if (transferable
300: .isDataFlavorSupported(FormObjectFlavor.LINKED_FORM_SET)) {
301: Collection forms = (Collection) transferable
302: .getTransferData(FormObjectFlavor.LINKED_FORM_SET);
303: return forms;
304: }
305: } catch (Exception e) {
306: e.printStackTrace();
307: }
308: return EmptyCollection.getInstance();
309: }
310:
311: /**
312: * Invokes a file chooser dialog which allows the user to select a form
313: * file. The form file is then checked to determine if it lies on the valid
314: * source path. If the form does not lie on a valid source path, an error
315: * dialog is displayed and null is returned.
316: */
317: public static File openLinkedFormFile() {
318: FileChooserConfig fcc = new FileChooserConfig(
319: ".form",
320: new TSFileFilter("jfrm,xml", "Form Files(*.jfrm,*.xml)"));
321: fcc.setParentComponent(getApplicationFrame());
322: File f = TSFileChooserFactory.showOpenDialog(fcc);
323: if (f != null) {
324: ProjectManager pmgr = (ProjectManager) JETARegistry
325: .lookup(ProjectManager.COMPONENT_ID);
326: /** check if the path is contained in a valid package for the project */
327: if (pmgr.isValidAbsolutePath(f.getPath())) {
328: return f;
329: } else {
330: String msg = I18N
331: .getLocalizedMessage("Selected_form_not_in_source_path");
332: String title = I18N.getLocalizedMessage("Error");
333:
334: JOptionPane.showMessageDialog(FormManagerDesignUtils
335: .getApplicationFrame(), msg, title,
336: JOptionPane.ERROR_MESSAGE);
337: }
338: }
339: return null;
340: }
341:
342: public static void registerForms(FormManager fmgr, Container cc) {
343: if (cc == null)
344: return;
345:
346: if (cc instanceof FormComponent)
347: fmgr.registerForm((FormComponent) cc);
348: else if (cc instanceof FormSurrogate)
349: fmgr.registerForm(((FormSurrogate) cc).getForm());
350:
351: if (cc instanceof FormSurrogate)
352: cc = ((FormSurrogate) cc).getForm();
353:
354: for (int index = 0; index < cc.getComponentCount(); index++) {
355: Component obj = cc.getComponent(index);
356: if (obj instanceof Container) {
357: registerForms(fmgr, (Container) obj);
358: }
359: }
360: }
361:
362: }
|