001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.etl.ui.view.wizards;
043:
044: import java.awt.Dialog;
045: import java.awt.event.ActionEvent;
046: import java.awt.event.ActionListener;
047: import java.beans.PropertyVetoException;
048: import java.util.ArrayList;
049: import java.util.Arrays;
050: import java.util.Collection;
051: import java.util.Collections;
052: import javax.swing.JButton;
053: import javax.swing.JScrollPane;
054: import net.java.hulp.i18n.Logger;
055: import org.netbeans.api.project.Project;
056: import org.netbeans.api.project.SourceGroup;
057: import org.netbeans.api.queries.VisibilityQuery;
058: import org.netbeans.modules.etl.logger.Localizer;
059: import org.netbeans.modules.etl.logger.LogUtil;
060: import org.openide.DialogDescriptor;
061: import org.openide.DialogDisplayer;
062: import org.openide.explorer.ExplorerManager;
063: import org.openide.explorer.view.BeanTreeView;
064: import org.openide.filesystems.FileObject;
065: import org.openide.loaders.DataFolder;
066: import org.openide.loaders.DataObject;
067: import org.openide.nodes.Children;
068: import org.openide.nodes.Node;
069: import org.openide.nodes.AbstractNode;
070: import org.openide.nodes.FilterNode;
071: import org.openide.nodes.NodeNotFoundException;
072: import org.openide.nodes.NodeOp;
073: import org.openide.util.NbBundle;
074:
075: /**
076: *
077: * @author phrebejk
078: */
079: public class BrowseFolders extends javax.swing.JPanel implements
080: ExplorerManager.Provider {
081:
082: private ExplorerManager manager;
083: private SourceGroup[] folders;
084: private BeanTreeView btv;
085: private Project project;
086:
087: private static JScrollPane SAMPLE_SCROLL_PANE = new JScrollPane();
088: private static transient final Logger mLogger = LogUtil
089: .getLogger(BrowseFolders.class.getName());
090: private static transient final Localizer mLoc = Localizer.get();
091:
092: /** Creates new form BrowseFolders */
093: public BrowseFolders(SourceGroup[] folders, Project project,
094: String preselectedFileName) {
095: initComponents();
096: this .folders = folders;
097: this .project = project;
098:
099: manager = new ExplorerManager();
100: AbstractNode rootNode = new AbstractNode(
101: new SourceGroupsChildren(folders, project));
102: manager.setRootContext(rootNode);
103:
104: // Create the templates view
105: btv = new BeanTreeView();
106: btv.setRootVisible(false);
107: btv
108: .setSelectionMode(javax.swing.tree.TreeSelectionModel.SINGLE_TREE_SELECTION);
109: btv.setBorder(SAMPLE_SCROLL_PANE.getBorder());
110: btv.setPopupAllowed(false);
111:
112: String nbBundle1 = mLoc.t("PRSR001: Folders:");
113: btv.getAccessibleContext().setAccessibleName(
114: Localizer.parse(nbBundle1));
115: String nbBundle2 = mLoc
116: .t("PRSR001: The tree contains the folders contained in the project's directory");
117: btv.getAccessibleContext().setAccessibleDescription(
118: Localizer.parse(nbBundle2));
119: expandSelection(preselectedFileName);
120: //expandAllNodes( btv, manager.getRootContext() );
121: folderPanel.add(btv, java.awt.BorderLayout.CENTER);
122: }
123:
124: // ExplorerManager.Provider implementation ---------------------------------
125:
126: public ExplorerManager getExplorerManager() {
127: return manager;
128: }
129:
130: /** This method is called from within the constructor to
131: * initialize the form.
132: * WARNING: Do NOT modify this code. The content of this method is
133: * always regenerated by the Form Editor.
134: */
135: private void initComponents() {//GEN-BEGIN:initComponents
136: java.awt.GridBagConstraints gridBagConstraints;
137:
138: jLabel1 = new javax.swing.JLabel();
139: folderPanel = new javax.swing.JPanel();
140:
141: setLayout(new java.awt.GridBagLayout());
142:
143: setBorder(new javax.swing.border.EmptyBorder(
144: new java.awt.Insets(12, 12, 12, 12)));
145:
146: String nbBundle3 = mLoc
147: .t("PRSR001: Browse folders to choose a target folder");
148: getAccessibleContext().setAccessibleName(
149: Localizer.parse(nbBundle3));
150:
151: String nbBundle4 = mLoc
152: .t("PRSR001: Browse folders to choose a target folder");
153: getAccessibleContext().setAccessibleDescription(
154: Localizer.parse(nbBundle4));
155:
156: String nbBundle5 = mLoc.t("PRSR001: F");
157: jLabel1.setDisplayedMnemonic(Localizer.parse(nbBundle5).charAt(
158: 0));
159: jLabel1.setLabelFor(folderPanel);
160:
161: String nbBundle6 = mLoc.t("PRSR001: Folders:");
162: jLabel1.setText(Localizer.parse(nbBundle6));
163: jLabel1.getAccessibleContext().setAccessibleName(
164: Localizer.parse(nbBundle6));
165: gridBagConstraints = new java.awt.GridBagConstraints();
166: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
167: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
168: gridBagConstraints.insets = new java.awt.Insets(0, 0, 2, 0);
169: add(jLabel1, gridBagConstraints);
170:
171: String nbBundle7 = mLoc.t("PRSR001: Folders:");
172: jLabel1.getAccessibleContext().setAccessibleName(
173: Localizer.parse(nbBundle7));
174:
175: folderPanel.setLayout(new java.awt.BorderLayout());
176:
177: gridBagConstraints = new java.awt.GridBagConstraints();
178: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
179: gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
180: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
181: gridBagConstraints.weightx = 1.0;
182: gridBagConstraints.weighty = 1.0;
183: add(folderPanel, gridBagConstraints);
184:
185: }//GEN-END:initComponents
186:
187: // Variables declaration - do not modify//GEN-BEGIN:variables
188: private javax.swing.JPanel folderPanel;
189: private javax.swing.JLabel jLabel1;
190:
191: // End of variables declaration//GEN-END:variables
192:
193: public static FileObject showDialog(SourceGroup[] folders,
194: Project project, String preselectedFileName) {
195:
196: BrowseFolders bf = new BrowseFolders(folders, project,
197: preselectedFileName);
198:
199: String nbBundle1 = mLoc.t("PRSR001: Select Folder");
200: String nbBundle2 = mLoc.t("PRSR001: Cancel");
201: JButton options[] = new JButton[] {
202: new JButton(Localizer.parse(nbBundle1)), // NOI18N
203: new JButton(Localizer.parse(nbBundle2)), // NOI18N
204: };
205:
206: OptionsListener optionsListener = new OptionsListener(bf);
207:
208: options[0].setActionCommand(OptionsListener.COMMAND_SELECT);
209: options[0].addActionListener(optionsListener);
210:
211: String nbBundle8 = mLoc.t("PRSR001: S");
212: options[0].setMnemonic(Localizer.parse(nbBundle8).charAt(0));
213:
214: String nbBundle9 = mLoc.t("PRSR001: Select Folder");
215: options[0].getAccessibleContext().setAccessibleName(
216: Localizer.parse(nbBundle9));
217:
218: String nbBundle10 = mLoc.t("PRSR001: N/A");
219: options[0].getAccessibleContext().setAccessibleDescription(
220: Localizer.parse(nbBundle10));
221: options[1].setActionCommand(OptionsListener.COMMAND_CANCEL);
222: options[1].addActionListener(optionsListener);
223:
224: String nbBundle11 = mLoc.t("PRSR001: Cancel");
225: options[1].getAccessibleContext().setAccessibleName(
226: Localizer.parse(nbBundle11));
227: String nbBundle12 = mLoc.t("PRSR001: N/A");
228: options[1].getAccessibleContext().setAccessibleDescription(
229: Localizer.parse(nbBundle12));
230:
231: DialogDescriptor dialogDescriptor = new DialogDescriptor(bf, // innerPane
232: "Browse Folders", // displayName
233: true, // modal
234: options, // options
235: options[0], // initial value
236: DialogDescriptor.BOTTOM_ALIGN, // options align
237: null, // helpCtx
238: null); // listener
239:
240: dialogDescriptor.setClosingOptions(new Object[] { options[0],
241: options[1] });
242: Dialog dialog = DialogDisplayer.getDefault().createDialog(
243: dialogDescriptor);
244: dialog
245: .getAccessibleContext()
246: .setAccessibleDescription(
247: "This is the dialog which enables user to browse folders");
248: dialog.setVisible(true);
249:
250: return optionsListener.getResult();
251: }
252:
253: private void expandSelection(String preselectedFileName) {
254:
255: Node root = manager.getRootContext();
256: Children ch = root.getChildren();
257: if (ch == Children.LEAF) {
258: return;
259: }
260: Node nodes[] = ch.getNodes(true);
261: Node sel = null;
262:
263: if (preselectedFileName != null
264: && preselectedFileName.length() > 0) {
265: // Try to find the node
266: for (int i = 0; i < nodes.length; i++) {
267: try {
268: sel = NodeOp.findPath(nodes[i], new String(
269: preselectedFileName).split("/"));
270: break;
271: } catch (NodeNotFoundException e) {
272: System.out.println(e.getMissingChildName());
273: // Will select the first node
274: }
275: }
276: }
277:
278: if (sel == null) {
279: // Node not found => expand first level
280: btv.expandNode(root);
281: for (int i = 0; i < nodes.length; i++) {
282: btv.expandNode(nodes[i]);
283: if (i == 0) {
284: sel = nodes[i];
285: }
286: }
287: }
288:
289: if (sel != null) {
290: // Select the node
291: try {
292: manager.setSelectedNodes(new Node[] { sel });
293: } catch (PropertyVetoException e) {
294: // No selection for some reason
295: }
296: }
297: }
298:
299: /*
300: private static void expandAllNodes( BeanTreeView btv, Node node ) {
301:
302: btv.expandNode( node );
303:
304: Children ch = node.getChildren();
305: if ( ch == Children.LEAF ) {
306: return;
307: }
308: Node nodes[] = ch.getNodes( true );
309:
310: for ( int i = 0; i < nodes.length; i++ ) {
311: expandAllNodes( btv, nodes[i] );
312: }
313: }
314: */
315:
316: // Innerclasses ------------------------------------------------------------
317: /** Children to be used to show FileObjects from given SourceGroups
318: */
319:
320: private static final class SourceGroupsChildren extends
321: Children.Keys {
322:
323: private SourceGroup[] groups;
324: private SourceGroup group;
325: private FileObject fo;
326: private Project project;
327:
328: public SourceGroupsChildren(FileObject fo, Project project) {
329: this .fo = fo;
330: this .project = project;
331: }
332:
333: public SourceGroupsChildren(SourceGroup[] groups,
334: Project project) {
335: this .groups = groups;
336: this .project = project;
337: }
338:
339: public SourceGroupsChildren(FileObject fo, SourceGroup group) {
340: this .fo = fo;
341: this .group = group;
342: }
343:
344: @Override
345: protected void addNotify() {
346: super .addNotify();
347: setKeys(getKeys());
348: }
349:
350: @Override
351: protected void removeNotify() {
352: setKeys(Collections.EMPTY_SET);
353: super .removeNotify();
354: }
355:
356: protected Node[] createNodes(Object key) {
357:
358: FileObject folder = null;
359:
360: if (key instanceof SourceGroup) {
361: folder = ((SourceGroup) key).getRootFolder();
362: group = (SourceGroup) key;
363: FilterNode fn = new FilterNode(
364: new PhysicalView.GroupNode(project, group,
365: folder.equals(project
366: .getProjectDirectory()),
367: DataFolder.findFolder(folder)),
368: new SourceGroupsChildren(folder, group));
369: return new Node[] { fn };
370: } else if (key instanceof Key) {
371: folder = ((Key) key).folder;
372: group = ((Key) key).group;
373: FilterNode fn = new FilterNode(DataFolder.findFolder(
374: folder).getNodeDelegate(),
375: new SourceGroupsChildren(folder, group));
376: return new Node[] { fn };
377: } else {
378: return new Node[0];
379: }
380: }
381:
382: private Collection getKeys() {
383: if (groups != null) {
384: return Arrays.asList(groups);
385: } else {
386: FileObject files[] = fo.getChildren();
387: ArrayList children = new ArrayList(files.length);
388:
389: for (int i = 0; i < files.length; i++) {
390: if (files[i].isFolder()
391: && group.contains(files[i])
392: && VisibilityQuery.getDefault().isVisible(
393: files[i])) {
394: children.add(new Key(files[i], group));
395: }
396: }
397: return children;
398: }
399: }
400:
401: private static class Key {
402: private FileObject folder;
403: private SourceGroup group;
404:
405: private Key(FileObject folder, SourceGroup group) {
406: this .folder = folder;
407: this .group = group;
408: }
409: }
410: }
411:
412: private static final class OptionsListener implements
413: ActionListener {
414:
415: public static final String COMMAND_SELECT = "SELECT";
416: public static final String COMMAND_CANCEL = "CANCEL";
417: private BrowseFolders browsePanel;
418: private FileObject result;
419:
420: public OptionsListener(BrowseFolders browsePanel) {
421: this .browsePanel = browsePanel;
422: }
423:
424: public void actionPerformed(ActionEvent e) {
425: String command = e.getActionCommand();
426:
427: if (COMMAND_SELECT.equals(command)) {
428: Node selection[] = browsePanel.getExplorerManager()
429: .getSelectedNodes();
430:
431: if (selection != null && selection.length > 0) {
432: DataObject dobj = (DataObject) selection[0]
433: .getLookup().lookup(DataObject.class);
434: if (dobj != null) {
435: FileObject fo = dobj.getPrimaryFile();
436: if (fo.isFolder()) {
437: result = fo;
438: }
439: }
440: }
441: }
442: }
443:
444: public FileObject getResult() {
445: return result;
446: }
447: }
448: }
|