001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019:
020: package org.netbeans.modules.sql.project.ui.wizards;
021:
022: import java.io.File;
023: import java.io.IOException;
024: import java.text.MessageFormat;
025:
026: import javax.swing.JFileChooser;
027: import javax.swing.event.DocumentEvent;
028: import javax.swing.event.DocumentListener;
029: import org.netbeans.modules.sql.project.ui.FoldersListSettings;
030:
031: import org.netbeans.spi.project.ui.support.ProjectChooser;
032:
033: import org.openide.WizardDescriptor;
034: import org.openide.filesystems.FileUtil;
035: import org.openide.util.NbBundle;
036:
037: public class PanelProjectLocationVisual extends SettingsPanel implements
038: DocumentListener {
039:
040: public static final String PROP_PROJECT_NAME = "projectName"; //NOI18N
041:
042: private PanelConfigureProject panel;
043:
044: /** Creates new form PanelProjectLocationVisual */
045: public PanelProjectLocationVisual(PanelConfigureProject panel) {
046: initComponents();
047: this .panel = panel;
048:
049: // Register listener on the textFields to make the automatic updates
050: projectNameTextField.getDocument().addDocumentListener(this );
051: projectLocationTextField.getDocument()
052: .addDocumentListener(this );
053: }
054:
055: /** This method is called from within the constructor to
056: * initialize the form.
057: * WARNING: Do NOT modify this code. The content of this method is
058: * always regenerated by the Form Editor.
059: */
060: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
061: private void initComponents() {
062: java.awt.GridBagConstraints gridBagConstraints;
063:
064: projectNameLabel = new javax.swing.JLabel();
065: projectNameTextField = new javax.swing.JTextField();
066: projectLocationLabel = new javax.swing.JLabel();
067: projectLocationTextField = new javax.swing.JTextField();
068: Button = new javax.swing.JButton();
069: createdFolderLabel = new javax.swing.JLabel();
070: createdFolderTextField = new javax.swing.JTextField();
071:
072: setLayout(new java.awt.GridBagLayout());
073:
074: projectNameLabel.setLabelFor(projectNameTextField);
075: org.openide.awt.Mnemonics.setLocalizedText(projectNameLabel,
076: org.openide.util.NbBundle.getMessage(
077: PanelProjectLocationVisual.class,
078: "LBL_NWP1_ProjectName_Label"));
079: gridBagConstraints = new java.awt.GridBagConstraints();
080: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
081: gridBagConstraints.insets = new java.awt.Insets(0, 0, 12, 0);
082: add(projectNameLabel, gridBagConstraints);
083:
084: gridBagConstraints = new java.awt.GridBagConstraints();
085: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
086: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
087: gridBagConstraints.weightx = 1.0;
088: gridBagConstraints.insets = new java.awt.Insets(0, 12, 12, 0);
089: add(projectNameTextField, gridBagConstraints);
090: projectNameTextField.getAccessibleContext()
091: .setAccessibleDescription(
092: org.openide.util.NbBundle.getMessage(
093: PanelProjectLocationVisual.class,
094: "ACS_LBL_NWP1_ProjectName_A11YDesc"));
095:
096: projectLocationLabel.setLabelFor(projectLocationTextField);
097: org.openide.awt.Mnemonics.setLocalizedText(
098: projectLocationLabel, org.openide.util.NbBundle
099: .getMessage(PanelProjectLocationVisual.class,
100: "LBL_NWP1_ProjectLocation_Label"));
101: gridBagConstraints = new java.awt.GridBagConstraints();
102: gridBagConstraints.gridy = 1;
103: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
104: gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0);
105: add(projectLocationLabel, gridBagConstraints);
106:
107: gridBagConstraints = new java.awt.GridBagConstraints();
108: gridBagConstraints.gridy = 1;
109: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
110: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
111: gridBagConstraints.weightx = 1.0;
112: gridBagConstraints.insets = new java.awt.Insets(0, 12, 5, 0);
113: add(projectLocationTextField, gridBagConstraints);
114: projectLocationTextField
115: .getAccessibleContext()
116: .setAccessibleDescription(
117: org.openide.util.NbBundle
118: .getMessage(
119: PanelProjectLocationVisual.class,
120: "ACS_LBL_NPW1_ProjectLocation_A11YDesc"));
121:
122: org.openide.awt.Mnemonics.setLocalizedText(Button,
123: org.openide.util.NbBundle.getMessage(
124: PanelProjectLocationVisual.class,
125: "LBL_NWP1_BrowseLocation_Button"));
126: Button.setActionCommand("BROWSE");
127: Button.addActionListener(new java.awt.event.ActionListener() {
128: public void actionPerformed(java.awt.event.ActionEvent evt) {
129: browseLocationAction(evt);
130: }
131: });
132:
133: gridBagConstraints = new java.awt.GridBagConstraints();
134: gridBagConstraints.gridy = 1;
135: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
136: gridBagConstraints.insets = new java.awt.Insets(0, 6, 5, 0);
137: add(Button, gridBagConstraints);
138: Button.getAccessibleContext().setAccessibleDescription(
139: org.openide.util.NbBundle.getMessage(
140: PanelProjectLocationVisual.class,
141: "ACS_LBL_NWP1_BrowseLocation_A11YDesc"));
142:
143: createdFolderLabel.setLabelFor(createdFolderTextField);
144: org.openide.awt.Mnemonics.setLocalizedText(createdFolderLabel,
145: org.openide.util.NbBundle.getMessage(
146: PanelProjectLocationVisual.class,
147: "LBL_NWP1_CreatedProjectFolder_Lablel"));
148: gridBagConstraints = new java.awt.GridBagConstraints();
149: gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
150: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
151: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
152: add(createdFolderLabel, gridBagConstraints);
153:
154: createdFolderTextField.setEditable(false);
155: gridBagConstraints = new java.awt.GridBagConstraints();
156: gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
157: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
158: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
159: gridBagConstraints.weightx = 1.0;
160: gridBagConstraints.weighty = 1.0;
161: gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 0);
162: add(createdFolderTextField, gridBagConstraints);
163: createdFolderTextField
164: .getAccessibleContext()
165: .setAccessibleDescription(
166: org.openide.util.NbBundle
167: .getMessage(
168: PanelProjectLocationVisual.class,
169: "ACS_LBL_NWP1_CreatedProjectFolder_A11YDesc"));
170:
171: }// </editor-fold>//GEN-END:initComponents
172:
173: private void browseLocationAction(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseLocationAction
174: String command = evt.getActionCommand();
175:
176: if ("BROWSE".equals(command)) { //NOI18N
177: JFileChooser chooser = new JFileChooser();
178: chooser.setDialogTitle(NbBundle.getMessage(
179: PanelProjectLocationVisual.class,
180: "LBL_NWP1_SelectProjectLocation")); //NOI18N
181: chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
182: String path = projectLocationTextField.getText();
183: if (path.length() > 0) {
184: File f = new File(path);
185: if (f.exists())
186: chooser.setSelectedFile(f);
187: }
188: if (JFileChooser.APPROVE_OPTION == chooser
189: .showOpenDialog(this )) {
190: File projectDir = chooser.getSelectedFile();
191: projectLocationTextField.setText(projectDir
192: .getAbsolutePath());
193: }
194: panel.fireChangeEvent();
195: }
196: }//GEN-LAST:event_browseLocationAction
197:
198: public void addNotify() {
199: super .addNotify();
200: //same problem as in 31086, initial focus on Cancel button
201: projectNameTextField.requestFocus();
202: }
203:
204: boolean valid(WizardDescriptor wizardDescriptor) {
205: String projectName = projectNameTextField.getText();
206: if (projectName.length() == 0
207: //String indexOf is not picking up \ char if this is the
208: // first char
209: || projectName.substring(0, 1).equals("\\")
210: || projectName.indexOf('/') >= 0 //NOI18N
211: || projectName.indexOf("\\") >= 0 //NOI18N
212: || projectName.indexOf(':') >= 0
213: || !isValidName(projectName)) { //NOI18N
214: wizardDescriptor.putProperty("WizardPanel_errorMessage", // NOI18N
215: NbBundle.getMessage(
216: PanelProjectLocationVisual.class,
217: "MSG_IllegalProjectName"));
218: return false; // Display name not specified
219: }
220:
221: if (projectName.indexOf(' ') >= 0) { //NOI18N
222: wizardDescriptor.putProperty("WizardPanel_errorMessage", // NOI18N
223: NbBundle.getMessage(
224: PanelProjectLocationVisual.class,
225: "MSG_IllegalProjectNameWithWhiteSpace"));
226: return false;
227: }
228:
229: File f = new File(projectLocationTextField.getText())
230: .getAbsoluteFile();
231: if (getCanonicalFile(f) == null) {
232: String message = NbBundle.getMessage(
233: PanelProjectLocationVisual.class,
234: "MSG_IllegalProjectLocation");
235: wizardDescriptor.putProperty("WizardPanel_errorMessage",
236: message);
237: return false;
238: }
239: final File destFolder = new File(createdFolderTextField
240: .getText()).getAbsoluteFile();
241: if (getCanonicalFile(destFolder) == null) {
242: String message = NbBundle.getMessage(
243: PanelProjectLocationVisual.class,
244: "MSG_IllegalProjectName");
245: wizardDescriptor.putProperty("WizardPanel_errorMessage",
246: message);
247: return false;
248: }
249:
250: File projLoc = FileUtil.normalizeFile(destFolder);
251: while (projLoc != null && !projLoc.exists()) {
252: projLoc = projLoc.getParentFile();
253: }
254: if (projLoc == null || !projLoc.canWrite()) {
255: wizardDescriptor.putProperty("WizardPanel_errorMessage", // NOI18N
256: NbBundle.getMessage(
257: PanelProjectLocationVisual.class,
258: "MSG_ProjectFolderReadOnly"));
259: return false;
260: }
261:
262: if (FileUtil.toFileObject(projLoc) == null) {
263: String message = NbBundle.getMessage(
264: PanelProjectLocationVisual.class,
265: "MSG_IllegalProjectLocation");
266: wizardDescriptor.putProperty("WizardPanel_errorMessage",
267: message);
268: return false;
269: }
270:
271: File[] kids = destFolder.listFiles();
272: if (destFolder.exists() && kids != null && kids.length > 0) {
273: // Folder exists and is not empty
274: wizardDescriptor.putProperty("WizardPanel_errorMessage", // NOI18N
275: NbBundle.getMessage(
276: PanelProjectLocationVisual.class,
277: "MSG_ProjectFolderExists"));
278: return false;
279: }
280: wizardDescriptor.putProperty("WizardPanel_errorMessage", // NOI18N
281: "");
282: return true;
283: }
284:
285: static boolean isValidName(String fileName) {
286: try {
287: boolean bValid = true;
288: File tempFile = new File(fileName);
289: String tempFileName = 0 + fileName;
290: File actualTempFile = File.createTempFile(tempFileName,
291: null);
292:
293: if (!FileUtil.normalizeFile(tempFile).equals(
294: tempFile.getCanonicalFile())) {
295: bValid = false;
296: }
297: actualTempFile.delete();
298: actualTempFile = null;
299: tempFile = null;
300: return bValid;
301: } catch (Exception e) {
302: return false;
303: }
304: }
305:
306: void store(WizardDescriptor d) {
307: String name = projectNameTextField.getText().trim();
308:
309: File destFolder = new File(createdFolderTextField.getText()
310: .trim());
311: d.putProperty(WizardProperties.PROJECT_DIR, FileUtil
312: .normalizeFile(destFolder));
313: d.putProperty(WizardProperties.NAME, name);
314:
315: File projectsDir = new File(this .projectLocationTextField
316: .getText());
317: if (projectsDir.isDirectory()) {
318: ProjectChooser.setProjectsFolder(projectsDir);
319: }
320: }
321:
322: void read(WizardDescriptor settings) {
323: File projectLocation = (File) settings
324: .getProperty(WizardProperties.PROJECT_DIR);
325: if (projectLocation == null)
326: projectLocation = ProjectChooser.getProjectsFolder();
327: else
328: projectLocation = projectLocation.getParentFile();
329:
330: projectLocationTextField.setText(projectLocation
331: .getAbsolutePath());
332:
333: String projectName = (String) settings
334: .getProperty(WizardProperties.NAME);
335: if (projectName == null) {
336: int baseCount = FoldersListSettings.getDefault()
337: .getNewProjectCount() + 1;
338: String formater = NbBundle.getMessage(
339: PanelProjectLocationVisual.class,
340: "LBL_NPW1_DefaultProjectName");
341: while ((projectName = validFreeProjectName(projectLocation,
342: formater, baseCount)) == null)
343: baseCount++;
344: }
345:
346: projectNameTextField.setText(projectName);
347: projectNameTextField.selectAll();
348: }
349:
350: // Variables declaration - do not modify//GEN-BEGIN:variables
351: private javax.swing.JButton Button;
352: private javax.swing.JLabel createdFolderLabel;
353: private javax.swing.JTextField createdFolderTextField;
354: private javax.swing.JLabel projectLocationLabel;
355: private javax.swing.JTextField projectLocationTextField;
356: private javax.swing.JLabel projectNameLabel;
357: protected javax.swing.JTextField projectNameTextField;
358:
359: // End of variables declaration//GEN-END:variables
360:
361: private static JFileChooser createChooser() {
362: JFileChooser chooser = new JFileChooser();
363: chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
364: chooser.setAcceptAllFileFilterUsed(false);
365:
366: return chooser;
367: }
368:
369: private String validFreeProjectName(final File parentFolder,
370: final String formater, final int index) {
371: String name = MessageFormat.format(formater,
372: new Object[] { new Integer(index) });
373: File file = new File(parentFolder, name);
374: return file.exists() ? null : name;
375: }
376:
377: // Implementation of DocumentListener --------------------------------------
378: public void changedUpdate(DocumentEvent e) {
379: updateTexts(e);
380: if (this .projectNameTextField.getDocument() == e.getDocument()) {
381: firePropertyChange(PROP_PROJECT_NAME, null,
382: this .projectNameTextField.getText());
383: }
384: }
385:
386: public void insertUpdate(DocumentEvent e) {
387: updateTexts(e);
388: if (this .projectNameTextField.getDocument() == e.getDocument()) {
389: firePropertyChange(PROP_PROJECT_NAME, null,
390: this .projectNameTextField.getText());
391: }
392: }
393:
394: public void removeUpdate(DocumentEvent e) {
395: updateTexts(e);
396: if (this .projectNameTextField.getDocument() == e.getDocument()) {
397: firePropertyChange(PROP_PROJECT_NAME, null,
398: this .projectNameTextField.getText());
399: }
400: }
401:
402: // End if implementation of DocumentListener -------------------------------
403:
404: /** Handles changes in the project name and project directory
405: */
406: private void updateTexts(DocumentEvent e) {
407: createdFolderTextField.setText(getCreatedFolderPath());
408:
409: panel.fireChangeEvent(); // Notify that the panel changed
410: }
411:
412: private String getCreatedFolderPath() {
413: StringBuffer folder = new StringBuffer(projectLocationTextField
414: .getText().trim());
415: if (!projectLocationTextField.getText()
416: .endsWith(File.separator))
417: folder.append(File.separatorChar);
418: folder.append(projectNameTextField.getText().trim());
419:
420: return folder.toString();
421: }
422:
423: static File getCanonicalFile(File file) {
424: try {
425: return file.getCanonicalFile();
426: } catch (IOException e) {
427: return null;
428: }
429: }
430: }
431:
432: //TODO implement check for project folder name and location
|