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-2006 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.mercurial.options;
043:
044: import java.awt.Dialog;
045: import java.awt.event.ActionEvent;
046: import java.awt.event.ActionListener;
047: import java.awt.event.MouseAdapter;
048: import java.awt.event.MouseEvent;
049: import java.awt.BorderLayout;
050: import java.io.File;
051: import javax.swing.JFileChooser;
052: import javax.swing.JButton;
053: import javax.swing.JOptionPane;
054: import java.util.ArrayList;
055: import java.util.List;
056: import java.beans.PropertyChangeListener;
057: import java.beans.PropertyChangeSupport;
058: import javax.swing.JComponent;
059: import javax.swing.filechooser.FileFilter;
060: import org.netbeans.modules.mercurial.Mercurial;
061: import org.netbeans.modules.mercurial.MercurialAnnotator;
062: import org.netbeans.modules.mercurial.HgModuleConfig;
063: import org.netbeans.modules.mercurial.options.PropertiesPanel;
064: import org.netbeans.modules.mercurial.options.PropertiesTable;
065: import org.netbeans.modules.mercurial.options.PropertiesTableModel;
066: import org.netbeans.spi.options.OptionsPanelController;
067: import org.netbeans.modules.versioning.util.AccessibleJFileChooser;
068: import org.openide.DialogDescriptor;
069: import org.openide.DialogDisplayer;
070: import org.openide.filesystems.FileUtil;
071: import org.openide.util.HelpCtx;
072: import org.openide.util.Lookup;
073: import org.openide.util.NbBundle;
074:
075: final class MercurialOptionsPanelController extends
076: OptionsPanelController implements ActionListener {
077:
078: private MercurialPanel panel;
079: private final PropertyChangeSupport pcs = new PropertyChangeSupport(
080: this );
081: private boolean changed;
082:
083: public MercurialOptionsPanelController() {
084:
085: panel = new MercurialPanel(this );
086: panel.execPathBrowseButton.addActionListener(this );
087: panel.exportFilenameBrowseButton.addActionListener(this );
088:
089: String tooltip = NbBundle.getMessage(MercurialPanel.class,
090: "MercurialPanel.annotationTextField.toolTipText",
091: MercurialAnnotator.LABELS); // NOI18N
092:
093: panel.annotationTextField.setToolTipText(tooltip);
094: panel.addButton.addActionListener(this );
095: panel.manageButton.addActionListener(this );
096: }
097:
098: public void update() {
099: getPanel().load();
100: changed = false;
101: }
102:
103: public void applyChanges() {
104: if (!validateFields())
105: return;
106:
107: getPanel().store();
108: // {folder} variable setting
109: Mercurial.getInstance().getMercurialAnnotator().refresh();
110: Mercurial.getInstance().refreshAllAnnotations();
111:
112: changed = false;
113: }
114:
115: public void cancel() {
116: // need not do anything special, if no changes have been persisted yet
117: }
118:
119: public boolean isValid() {
120: return getPanel().valid();
121: }
122:
123: public boolean isChanged() {
124: return changed;
125: }
126:
127: public HelpCtx getHelpCtx() {
128: return new HelpCtx(MercurialOptionsPanelController.class);
129: }
130:
131: public JComponent getComponent(Lookup masterLookup) {
132: return getPanel();
133: }
134:
135: public void addPropertyChangeListener(PropertyChangeListener l) {
136: pcs.addPropertyChangeListener(l);
137: }
138:
139: public void removePropertyChangeListener(PropertyChangeListener l) {
140: pcs.removePropertyChangeListener(l);
141: }
142:
143: public void actionPerformed(ActionEvent evt) {
144: if (evt.getSource() == panel.execPathBrowseButton) {
145: onExecPathBrowseClick();
146: } else if (evt.getSource() == panel.exportFilenameBrowseButton) {
147: onExportFilenameBrowseClick();
148: } else if (evt.getSource() == panel.addButton) {
149: onAddClick();
150: } else if (evt.getSource() == panel.manageButton) {
151: onManageClick();
152: }
153: }
154:
155: private File getExportFile() {
156: String execPath = panel.exportFilenameTextField.getText();
157: return FileUtil.normalizeFile(new File(execPath));
158: }
159:
160: private File getExecutableFile() {
161: String execPath = panel.executablePathTextField.getText();
162: return FileUtil.normalizeFile(new File(execPath));
163: }
164:
165: private Boolean validateFields() {
166: String username = panel.userNameTextField.getText();
167: if (!HgModuleConfig.getDefault().isUserNameValid(username)) {
168: JOptionPane.showMessageDialog(null, NbBundle.getMessage(
169: MercurialPanel.class, "MSG_WARN_USER_NAME_TEXT"), // NOI18N
170: NbBundle.getMessage(MercurialPanel.class,
171: "MSG_WARN_FIELD_TITLE"), // NOI18N
172: JOptionPane.WARNING_MESSAGE);
173: return false;
174: }
175: String execpath = panel.executablePathTextField.getText();
176: if (!HgModuleConfig.getDefault().isExecPathValid(execpath)) {
177: JOptionPane.showMessageDialog(null, NbBundle.getMessage(
178: MercurialPanel.class, "MSG_WARN_EXEC_PATH_TEXT"), // NOI18N
179: NbBundle.getMessage(MercurialPanel.class,
180: "MSG_WARN_FIELD_TITLE"), // NOI18N
181: JOptionPane.WARNING_MESSAGE);
182: return false;
183: }
184: return true;
185: }
186:
187: private void onExportFilenameBrowseClick() {
188: File oldFile = getExecutableFile();
189: JFileChooser fileChooser = new AccessibleJFileChooser(NbBundle
190: .getMessage(MercurialOptionsPanelController.class,
191: "ACSD_ExportBrowseFolder"), oldFile); // NOI18N
192: fileChooser.setDialogTitle(NbBundle.getMessage(
193: MercurialOptionsPanelController.class,
194: "ExportBrowse_title")); // NOI18N
195: fileChooser.setMultiSelectionEnabled(false);
196: FileFilter[] old = fileChooser.getChoosableFileFilters();
197: for (int i = 0; i < old.length; i++) {
198: FileFilter fileFilter = old[i];
199: fileChooser.removeChoosableFileFilter(fileFilter);
200: }
201: fileChooser.showDialog(panel, NbBundle.getMessage(
202: MercurialOptionsPanelController.class, "OK_Button")); // NOI18N
203: File f = fileChooser.getSelectedFile();
204: if (f != null) {
205: panel.exportFilenameTextField.setText(f.getAbsolutePath());
206: }
207: }
208:
209: private void onExecPathBrowseClick() {
210: File oldFile = getExportFile();
211: JFileChooser fileChooser = new AccessibleJFileChooser(NbBundle
212: .getMessage(MercurialOptionsPanelController.class,
213: "ACSD_BrowseFolder"), oldFile); // NOI18N
214: fileChooser.setDialogTitle(NbBundle.getMessage(
215: MercurialOptionsPanelController.class, "Browse_title")); // NOI18N
216: fileChooser.setMultiSelectionEnabled(false);
217: FileFilter[] old = fileChooser.getChoosableFileFilters();
218: for (int i = 0; i < old.length; i++) {
219: FileFilter fileFilter = old[i];
220: fileChooser.removeChoosableFileFilter(fileFilter);
221: }
222: fileChooser.addChoosableFileFilter(new FileFilter() {
223: public boolean accept(File f) {
224: return f.isDirectory();
225: }
226:
227: public String getDescription() {
228: return NbBundle.getMessage(
229: MercurialOptionsPanelController.class,
230: "MercurialExec");// NOI18N
231: }
232: });
233: fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
234: fileChooser.showDialog(panel, NbBundle.getMessage(
235: MercurialOptionsPanelController.class, "OK_Button")); // NOI18N
236: File f = fileChooser.getSelectedFile();
237: if (f != null) {
238: panel.executablePathTextField.setText(f.getAbsolutePath());
239: }
240: }
241:
242: private MercurialPanel getPanel() {
243: if (panel == null) {
244: panel = new MercurialPanel(this );
245: }
246: return panel;
247: }
248:
249: void changed() {
250: if (!changed) {
251: changed = true;
252: pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED,
253: false, true);
254: }
255: pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null,
256: null);
257: }
258:
259: private class LabelVariable {
260: private String description;
261: private String variable;
262:
263: public LabelVariable(String variable, String description) {
264: this .description = description;
265: this .variable = variable;
266: }
267:
268: public String toString() {
269: return description;
270: }
271:
272: public String getDescription() {
273: return description;
274: }
275:
276: public String getVariable() {
277: return variable;
278: }
279: }
280:
281: private void onAddClick() {
282: LabelsPanel labelsPanel = new LabelsPanel();
283: List<LabelVariable> variables = new ArrayList<LabelVariable>(
284: MercurialAnnotator.LABELS.length);
285: for (int i = 0; i < MercurialAnnotator.LABELS.length; i++) {
286: LabelVariable variable = new LabelVariable(
287: MercurialAnnotator.LABELS[i],
288: "{"
289: + MercurialAnnotator.LABELS[i]
290: + "} - "
291: + NbBundle
292: .getMessage(
293: MercurialPanel.class,
294: "MercurialPanel.label."
295: + MercurialAnnotator.LABELS[i]) // NOI18N
296: );
297: variables.add(variable);
298: }
299: labelsPanel.labelsList.setListData(variables
300: .toArray(new LabelVariable[variables.size()]));
301:
302: String title = NbBundle.getMessage(MercurialPanel.class,
303: "MercurialPanel.labelVariables.title"); // NOI18N
304: String acsd = NbBundle.getMessage(MercurialPanel.class,
305: "MercurialPanel.labelVariables.acsd"); // NOI18N
306:
307: DialogDescriptor dialogDescriptor = new DialogDescriptor(
308: labelsPanel, title);
309: dialogDescriptor.setModal(true);
310: dialogDescriptor.setValid(true);
311:
312: final Dialog dialog = DialogDisplayer.getDefault()
313: .createDialog(dialogDescriptor);
314: dialog.getAccessibleContext().setAccessibleDescription(acsd);
315:
316: labelsPanel.labelsList.addMouseListener(new MouseAdapter() {
317: public void mouseClicked(MouseEvent e) {
318: if (e.getClickCount() == 2) {
319: dialog.setVisible(false);
320: }
321: }
322: });
323:
324: dialog.setVisible(true);
325:
326: if (DialogDescriptor.OK_OPTION.equals(dialogDescriptor
327: .getValue())) {
328:
329: Object[] selection = (Object[]) labelsPanel.labelsList
330: .getSelectedValues();
331:
332: String variable = ""; // NOI18N
333: for (int i = 0; i < selection.length; i++) {
334: variable += "{"
335: + ((LabelVariable) selection[i]).getVariable()
336: + "}"; // NOI18N
337: }
338:
339: String annotation = panel.annotationTextField.getText();
340:
341: int pos = panel.annotationTextField.getCaretPosition();
342: if (pos < 0)
343: pos = annotation.length();
344:
345: StringBuffer sb = new StringBuffer(annotation.length()
346: + variable.length());
347: sb.append(annotation.substring(0, pos));
348: sb.append(variable);
349: if (pos < annotation.length()) {
350: sb.append(annotation
351: .substring(pos, annotation.length()));
352: }
353: panel.annotationTextField.setText(sb.toString());
354: panel.annotationTextField.requestFocus();
355: panel.annotationTextField.setCaretPosition(pos
356: + variable.length());
357: }
358: }
359:
360: private void onManageClick() {
361: final PropertiesPanel panel = new PropertiesPanel();
362:
363: final PropertiesTable propTable;
364:
365: propTable = new PropertiesTable(panel.labelForTable,
366: PropertiesTable.PROPERTIES_COLUMNS,
367: new String[] { PropertiesTableModel.COLUMN_NAME_VALUE });
368:
369: panel.setPropertiesTable(propTable);
370:
371: JComponent component = propTable.getComponent();
372:
373: panel.propsPanel.setLayout(new BorderLayout());
374:
375: panel.propsPanel.add(component, BorderLayout.CENTER);
376:
377: HgExtProperties hgProperties = new HgExtProperties(panel,
378: propTable, null);
379:
380: DialogDescriptor dd = new DialogDescriptor(panel, NbBundle
381: .getMessage(MercurialOptionsPanelController.class,
382: "CTL_PropertiesDialog_Title", null), true, null); // NOI18N
383: final JButton okButton = new JButton(NbBundle.getMessage(
384: MercurialOptionsPanelController.class,
385: "CTL_Properties_Action_OK")); // NOI18N
386: okButton.getAccessibleContext().setAccessibleDescription(
387: NbBundle.getMessage(
388: MercurialOptionsPanelController.class,
389: "CTL_Properties_Action_OK")); // NOI18N
390: final JButton cancelButton = new JButton(NbBundle.getMessage(
391: MercurialOptionsPanelController.class,
392: "CTL_Properties_Action_Cancel")); // NOI18N
393: cancelButton.getAccessibleContext().setAccessibleDescription(
394: NbBundle.getMessage(
395: MercurialOptionsPanelController.class,
396: "CTL_Properties_Action_Cancel")); // NOI18N
397: dd.setOptions(new Object[] { okButton, cancelButton }); // NOI18N
398: dd
399: .setHelpCtx(new HelpCtx(
400: MercurialOptionsPanelController.class));
401: panel.putClientProperty("contentTitle", null); // NOI18N
402: panel.putClientProperty("DialogDescriptor", dd); // NOI18N
403: Dialog dialog = DialogDisplayer.getDefault().createDialog(dd);
404: dialog.getAccessibleContext().setAccessibleDescription(
405: NbBundle.getMessage(
406: MercurialOptionsPanelController.class,
407: "CTL_PropertiesDialog_Title")); // NOI18N
408:
409: dialog.pack();
410: dialog.setVisible(true);
411: if (dd.getValue() == okButton) {
412: hgProperties.setProperties();
413: }
414: }
415: }
|