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: * If you wish your version of this file to be governed by only the CDDL
025: * or only the GPL Version 2, indicate your decision by adding
026: * "[Contributor] elects to include this software in this distribution
027: * under the [CDDL or GPL Version 2] license." If you do not indicate a
028: * single choice of license, a recipient has the option to distribute
029: * your version of this file under either the CDDL, the GPL Version 2 or
030: * to extend the choice of license to its licensees as provided above.
031: * However, if you add GPL Version 2 code and therefore, elected the GPL
032: * Version 2 license, then the option applies only if the new code is
033: * made subject to such option by the copyright holder.
034: *
035: * Contributor(s):
036: *
037: * Portions Copyrighted 2007 Sun Microsystems, Inc.
038: */
039: package org.netbeans.modules.ruby.hints.infrastructure;
040:
041: import java.awt.Dialog;
042: import java.awt.Dimension;
043: import java.io.IOException;
044: import java.io.Reader;
045: import java.io.StringReader;
046: import java.io.Writer;
047: import javax.swing.JButton;
048: import javax.swing.JComponent;
049: import javax.swing.SwingUtilities;
050: import javax.swing.text.StyledDocument;
051: import org.netbeans.modules.gsf.api.CompilationInfo;
052: import org.netbeans.api.lexer.Language;
053: import org.netbeans.modules.ruby.hints.options.HintsAdvancedOption;
054: import org.netbeans.modules.ruby.hints.spi.PreviewableFix;
055: import org.netbeans.spi.editor.hints.ChangeInfo;
056: import org.netbeans.spi.editor.hints.Fix;
057: import org.openide.util.NbBundle;
058:
059: import org.netbeans.api.diff.DiffController;
060: import org.netbeans.api.diff.Difference;
061: import org.netbeans.api.diff.StreamSource;
062: import org.netbeans.modules.gsf.api.OffsetRange;
063: import org.netbeans.editor.BaseDocument;
064: import org.netbeans.modules.ruby.hints.spi.EditList;
065: import org.netbeans.spi.editor.hints.EnhancedFix;
066: import org.openide.DialogDescriptor;
067: import org.openide.DialogDisplayer;
068: import org.openide.text.NbDocument;
069:
070: /**
071: * Offer a preview for hints (that support it)
072: *
073: * @author Tor Norbye
074: */
075: public class PreviewHintFix implements EnhancedFix {
076:
077: private CompilationInfo info;
078: private PreviewableFix fix;
079: private final String sortText;
080:
081: public PreviewHintFix(CompilationInfo info, PreviewableFix fix,
082: String sortText) {
083: this .info = info;
084: this .fix = fix;
085: this .sortText = sortText;
086: }
087:
088: public String getText() {
089: // Indent Preview entries. I can't put the whitespace in the bundle file
090: // because strings seem to get trimmed by the NbBundle call.
091: return " "
092: + NbBundle.getMessage(HintsAdvancedOption.class,
093: "PreviewHint");
094: }
095:
096: public ChangeInfo implement() throws Exception {
097: EditList edits = fix.getEditList();
098:
099: BaseDocument oldDoc = (BaseDocument) info.getDocument();
100: //OffsetRange range = edits.getRange();
101: OffsetRange range = new OffsetRange(0, oldDoc.getLength());
102: String oldSource = oldDoc.getText(range.getStart(), range
103: .getEnd());
104:
105: BaseDocument newDoc = new BaseDocument(null, false);
106:
107: Language language = (Language) oldDoc
108: .getProperty(Language.class);
109: newDoc.putProperty(Language.class, language);
110: String mimeType = (String) oldDoc.getProperty("mimeType");
111: newDoc.putProperty("mimeType", mimeType);
112: newDoc.insertString(0, oldSource, null);
113: edits.applyToDocument(newDoc);
114: String newSource = newDoc.getText(0, newDoc.getLength());
115:
116: String oldTitle = NbBundle.getMessage(
117: HintsAdvancedOption.class, "CurrentSource");
118: String newTitle = NbBundle.getMessage(
119: HintsAdvancedOption.class, "FixedSource");
120:
121: final DiffController diffView = DiffController.create(
122: new DiffSource(oldSource, oldTitle), new DiffSource(
123: newSource, newTitle));
124:
125: JComponent jc = diffView.getJComponent();
126:
127: jc.setPreferredSize(new Dimension(800, 600));
128:
129: // Warp view to a particular diff?
130: // I can't just always jump to difference number 0, because when a hint
131: // has changed only the whitespace (such as the fix which moves =begin entries to column 0)
132: // there are no diffs, even though I want to jump to the relevant line.
133: final int index = 0;
134: final int firstLine = diffView.getDifferenceCount() == 0 ? NbDocument
135: .findLineNumber((StyledDocument) oldDoc, edits
136: .getRange().getStart())
137: : -1;
138: SwingUtilities.invokeLater(new Runnable() {
139:
140: public void run() {
141: if (firstLine != -1) {
142: diffView.setLocation(DiffController.DiffPane.Base,
143: DiffController.LocationType.LineNumber,
144: firstLine);
145: } else if (diffView.getDifferenceCount() > 0) {
146: diffView
147: .setLocation(
148: DiffController.DiffPane.Base,
149: DiffController.LocationType.DifferenceIndex,
150: index);
151: }
152: }
153: });
154:
155: JButton apply = new JButton(NbBundle.getMessage(
156: HintsAdvancedOption.class, "Apply"));
157: JButton ok = new JButton(NbBundle.getMessage(
158: HintsAdvancedOption.class, "Ok"));
159: JButton cancel = new JButton(NbBundle.getMessage(
160: HintsAdvancedOption.class, "Cancel"));
161: String dialogTitle = NbBundle.getMessage(
162: HintsAdvancedOption.class, "PreviewTitle", fix
163: .getDescription());
164:
165: DialogDescriptor descriptor = new DialogDescriptor(jc,
166: dialogTitle, true, new Object[] { apply, ok, cancel },
167: ok, DialogDescriptor.DEFAULT_ALIGN, null, null, true);
168: Dialog dlg = null;
169:
170: try {
171: dlg = DialogDisplayer.getDefault().createDialog(descriptor);
172: dlg.setVisible(true);
173: if (descriptor.getValue() == apply) {
174: fix.implement();
175: }
176: } finally {
177: if (dlg != null) {
178: dlg.dispose();
179: }
180: }
181:
182: return null;
183: }
184:
185: public CharSequence getSortText() {
186: return sortText;
187: }
188:
189: private class DiffSource extends StreamSource {
190:
191: private String source;
192: private String title;
193:
194: private DiffSource(String source, String title) {
195: this .source = source;
196: this .title = title;
197: }
198:
199: @Override
200: public String getName() {
201: return "?"; // unused?
202: }
203:
204: @Override
205: public String getTitle() {
206: return title;
207: }
208:
209: @Override
210: public String getMIMEType() {
211: return info.getFileObject().getMIMEType();
212: }
213:
214: @Override
215: public Reader createReader() throws IOException {
216: return new StringReader(source);
217: }
218:
219: @Override
220: public Writer createWriter(Difference[] conflicts)
221: throws IOException {
222: throw new UnsupportedOperationException(
223: "Not supported yet.");
224: }
225:
226: @Override
227: public boolean isEditable() {
228: return false;
229: }
230: }
231: }
|