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: package org.netbeans.modules.subversion.ui.update;
042:
043: import java.awt.Dialog;
044: import java.awt.event.ActionEvent;
045: import java.awt.event.ActionListener;
046: import java.beans.PropertyChangeEvent;
047: import java.beans.PropertyChangeListener;
048: import java.net.MalformedURLException;
049: import java.util.logging.Level;
050: import javax.swing.JButton;
051: import javax.swing.JRadioButton;
052: import javax.swing.event.DocumentEvent;
053: import javax.swing.event.DocumentListener;
054: import org.netbeans.modules.subversion.RepositoryFile;
055: import org.netbeans.modules.subversion.Subversion;
056: import org.netbeans.modules.subversion.ui.browser.RepositoryPaths;
057: import org.openide.DialogDescriptor;
058: import org.openide.DialogDisplayer;
059: import org.openide.util.HelpCtx;
060: import org.tigris.subversion.svnclientadapter.SVNRevision;
061:
062: /**
063: *
064: * @author Tomas Stupka
065: */
066: public class RevertModifications implements PropertyChangeListener {
067:
068: private RevertModificationsPanel panel;
069: private JButton okButton;
070: private JButton cancelButton;
071: private RevertType[] types;
072:
073: public static class RevisionInterval {
074: public RevisionInterval(SVNRevision revision) {
075: this .startRevision = revision;
076: this .endRevision = revision;
077: }
078:
079: public RevisionInterval(SVNRevision startRevision,
080: SVNRevision endRevision) {
081: this .startRevision = startRevision;
082: this .endRevision = endRevision;
083: }
084:
085: SVNRevision startRevision;
086: SVNRevision endRevision;
087: }
088:
089: /** Creates a new instance of RevertModifications */
090: public RevertModifications(RepositoryFile repositoryFile) {
091: this (repositoryFile, null);
092: }
093:
094: /** Creates a new instance of RevertModifications */
095: public RevertModifications(RepositoryFile repositoryFile,
096: String defaultRevision) {
097: OneCommitRevertType ocrt = new OneCommitRevertType(
098: repositoryFile, getPanel().oneCommitRadioButton);
099: LocalRevertType lrt = new LocalRevertType(
100: getPanel().localChangesRadioButton);
101: types = new RevertType[] {
102: lrt,
103: ocrt,
104: new MoreCommitsRevertType(repositoryFile,
105: getPanel().moreCommitsRadioButton) };
106: okButton = new JButton(org.openide.util.NbBundle.getMessage(
107: RevertModifications.class,
108: "CTL_RevertForm_Action_Revert")); // NOI18N
109: okButton.getAccessibleContext().setAccessibleDescription(
110: org.openide.util.NbBundle.getMessage(
111: RevertModifications.class,
112: "ACSD_RevertForm_Action_Revert")); // NOI18N
113: cancelButton = new JButton(org.openide.util.NbBundle
114: .getMessage(RevertModifications.class,
115: "CTL_RevertForm_Action_Cancel")); // NOI18N
116: cancelButton.getAccessibleContext().setAccessibleDescription(
117: org.openide.util.NbBundle.getMessage(
118: RevertModifications.class,
119: "ACSD_RevertForm_Action_Cancel")); // NOI18N
120: if (defaultRevision != null) {
121: panel.oneCommitRadioButton.setSelected(true);
122: panel.oneRevisionTextField.setText(defaultRevision);
123: ocrt.actionPerformed(null);
124: } else {
125: panel.localChangesRadioButton.setSelected(true);
126: lrt.actionPerformed(null);
127: }
128: }
129:
130: private RevertModificationsPanel getPanel() {
131: if (panel == null) {
132: panel = new RevertModificationsPanel();
133: }
134: return panel;
135: }
136:
137: public RevisionInterval getRevisionInterval() {
138: for (int i = 0; i < types.length; i++) {
139: if (types[i].isSelected()) {
140: return types[i].getRevisionInterval();
141: }
142: }
143: return null;
144: }
145:
146: public boolean revertNewFiles() {
147: for (int i = 0; i < types.length; i++) {
148: if (types[i].isSelected()) {
149: return types[i].revertNewFiles();
150: }
151: }
152: return false;
153: }
154:
155: public boolean showDialog() {
156: DialogDescriptor dialogDescriptor = new DialogDescriptor(panel,
157: org.openide.util.NbBundle.getMessage(
158: RevertModifications.class, "CTL_RevertDialog")); // NOI18N
159: dialogDescriptor.setOptions(new Object[] { okButton,
160: cancelButton });
161:
162: dialogDescriptor.setModal(true);
163: dialogDescriptor.setHelpCtx(new HelpCtx(this .getClass()));
164: dialogDescriptor.setValid(false);
165:
166: Dialog dialog = DialogDisplayer.getDefault().createDialog(
167: dialogDescriptor);
168: dialog.getAccessibleContext()
169: .setAccessibleDescription(
170: org.openide.util.NbBundle.getMessage(
171: RevertModifications.class,
172: "ACSD_RevertDialog")); // NOI18N
173: dialog.setVisible(true);
174: dialog.setResizable(false);
175: boolean ret = dialogDescriptor.getValue() == okButton;
176: return ret;
177: }
178:
179: public void propertyChange(PropertyChangeEvent evt) {
180: if (evt.getPropertyName().equals(RepositoryPaths.PROP_VALID)) {
181: if (okButton != null) {
182: boolean valid = ((Boolean) evt.getNewValue())
183: .booleanValue();
184: okButton.setEnabled(valid);
185: }
186: }
187: }
188:
189: protected void setMoreCommitsFieldsEnabled(boolean b) {
190: getPanel().startRevisionTextField.setEnabled(b);
191: getPanel().endRevisionTextField.setEnabled(b);
192: getPanel().startSearchButton.setEnabled(b);
193: getPanel().endSearchButton.setEnabled(b);
194: }
195:
196: protected void setOneCommitFieldsEnabled(boolean b) {
197: getPanel().oneRevisionSearchButton.setEnabled(b);
198: getPanel().oneRevisionTextField.setEnabled(b);
199: }
200:
201: private abstract class RevertType implements ActionListener,
202: DocumentListener {
203: private JRadioButton button;
204:
205: RevertType(JRadioButton button) {
206: this .button = button;
207: button.addActionListener(this );
208: }
209:
210: boolean isSelected() {
211: return button.isSelected();
212: }
213:
214: boolean revertNewFiles() {
215: return panel.revertNewFilesCheckBox.isSelected();
216: }
217:
218: public void insertUpdate(DocumentEvent e) {
219: validateUserInput();
220: }
221:
222: public void removeUpdate(DocumentEvent e) {
223: validateUserInput();
224: }
225:
226: public void changedUpdate(DocumentEvent e) {
227: validateUserInput();
228: }
229:
230: void validateUserInput() {
231: // default means nothing to do
232: }
233:
234: RevisionInterval getRevisionInterval() {
235: return null; // default means null
236: }
237:
238: protected SVNRevision getRevision(RepositoryPaths path) {
239: try {
240: return path.getRepositoryFiles()[0].getRevision();
241: } catch (NumberFormatException ex) {
242: // should be already checked and
243: // not happen at this place anymore
244: Subversion.LOG.log(Level.INFO, null, ex);
245: } catch (MalformedURLException ex) {
246: // should be already checked and
247: // not happen at this place anymore
248: Subversion.LOG.log(Level.INFO, null, ex);
249: }
250: return null;
251: }
252:
253: protected boolean validateRevision(SVNRevision revision) {
254: boolean valid = revision == null
255: || revision.equals(SVNRevision.HEAD)
256: || revision.getKind() == SVNRevision.Kind.number;
257: RevertModifications.this .okButton.setEnabled(valid);
258: return valid;
259: }
260: }
261:
262: private class LocalRevertType extends RevertType {
263:
264: LocalRevertType(JRadioButton button) {
265: super (button);
266: }
267:
268: RevertModifications.RevisionInterval getRevisionInterval() {
269: return null;
270: }
271:
272: public void actionPerformed(ActionEvent e) {
273: setOneCommitFieldsEnabled(false);
274: setMoreCommitsFieldsEnabled(false);
275: }
276: }
277:
278: private class OneCommitRevertType extends RevertType {
279:
280: private RepositoryPaths oneRevisionPath;
281:
282: OneCommitRevertType(RepositoryFile repositoryFile,
283: JRadioButton button) {
284: super (button);
285: oneRevisionPath = new RepositoryPaths(repositoryFile, null,
286: null, getPanel().oneRevisionTextField,
287: getPanel().oneRevisionSearchButton);
288: oneRevisionPath
289: .addPropertyChangeListener(RevertModifications.this );
290: }
291:
292: RevertModifications.RevisionInterval getRevisionInterval() {
293: SVNRevision revision = getRevision(oneRevisionPath);
294: RevisionInterval ret = new RevisionInterval(revision);
295: return ret;
296: }
297:
298: void validateUserInput() {
299: validateRevision(getRevision(oneRevisionPath));
300: }
301:
302: public void actionPerformed(ActionEvent e) {
303: setOneCommitFieldsEnabled(true);
304: setMoreCommitsFieldsEnabled(false);
305: validateUserInput();
306: }
307:
308: }
309:
310: private class MoreCommitsRevertType extends RevertType {
311:
312: private RepositoryPaths endPath;
313: private RepositoryPaths startPath;
314:
315: MoreCommitsRevertType(RepositoryFile repositoryFile,
316: JRadioButton button) {
317: super (button);
318: startPath = new RepositoryPaths(repositoryFile, null, null,
319: getPanel().startRevisionTextField,
320: getPanel().startSearchButton);
321: startPath
322: .addPropertyChangeListener(RevertModifications.this );
323:
324: endPath = new RepositoryPaths(repositoryFile, null, null,
325: getPanel().endRevisionTextField,
326: getPanel().endSearchButton);
327: endPath.addPropertyChangeListener(RevertModifications.this );
328: }
329:
330: RevertModifications.RevisionInterval getRevisionInterval() {
331: SVNRevision revision1 = getRevision(startPath);
332: SVNRevision revision2 = getRevision(endPath);
333: if (revision1 == null || revision2 == null) {
334: return null;
335: }
336:
337: return getResortedRevisionInterval(revision1, revision2);
338: }
339:
340: void validateUserInput() {
341: if (!validateRevision(getRevision(startPath))) {
342: return;
343: }
344: if (!validateRevision(getRevision(endPath))) {
345: return;
346: }
347: }
348:
349: public void actionPerformed(ActionEvent e) {
350: setMoreCommitsFieldsEnabled(true);
351: setOneCommitFieldsEnabled(false);
352: validateUserInput();
353: }
354:
355: private RevisionInterval getResortedRevisionInterval(
356: SVNRevision revision1, SVNRevision revision2) {
357: RevisionInterval ret;
358: if (revision1.equals(SVNRevision.HEAD)
359: && revision1.equals(SVNRevision.HEAD)) {
360: ret = new RevisionInterval(revision1, revision2);
361: } else if (revision1.equals(SVNRevision.HEAD)) {
362: ret = new RevisionInterval(revision2, revision1);
363: } else if (revision2.equals(SVNRevision.HEAD)) {
364: ret = new RevisionInterval(revision1, revision2);
365: } else {
366: Long r1 = Long.parseLong(revision1.toString());
367: Long r2 = Long.parseLong(revision2.toString());
368: if (r1.compareTo(r2) < 0) {
369: ret = new RevisionInterval(revision1, revision2);
370: } else {
371: ret = new RevisionInterval(revision2, revision1);
372: }
373: }
374: return ret;
375: }
376:
377: }
378:
379: }
|