*/
package com.intellij.lang.java;
-import com.intellij.lang.refactoring.DefaultRefactoringSupportProvider;
+import com.intellij.lang.refactoring.RefactoringSupportProvider;
import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.search.LocalSearchScope;
/**
* @author ven
*/
-public class JavaRefactoringSupportProvider extends DefaultRefactoringSupportProvider {
+public class JavaRefactoringSupportProvider extends RefactoringSupportProvider {
public boolean isSafeDeleteAvailable(PsiElement element) {
return element instanceof PsiClass || element instanceof PsiMethod || element instanceof PsiField ||
(element instanceof PsiParameter && ((PsiParameter)element).getDeclarationScope() instanceof PsiMethod) ||
return new IntroduceFieldHandler();
}
- public boolean doInplaceRenameFor(final PsiElement element, final PsiElement context) {
+ public boolean isInplaceRenameAvailable(final PsiElement element, final PsiElement context) {
return mayRenameInplace(element, context);
}
XmlTag[] getDirectiveTags(JspDirectiveKind directiveKind, final boolean searchInIncludes);
XmlTag createDirective(XmlTag context, JspDirectiveKind directiveKind);
+ XmlTag createDirective(JspDirectiveKind directiveKind);
/**
* Method with a bad name. Returns file corresponding to getTemplateDataLanguage() method of ViewProvider
@NotNull
JspxFileViewProvider getViewProvider();
+
+ XmlTag getRootTag();
}
*/
package com.intellij.lang;
-import com.intellij.lang.refactoring.DefaultRefactoringSupportProvider;
import com.intellij.lang.refactoring.RefactoringSupportProvider;
public class LanguageRefactoringSupport extends LanguageExtension<RefactoringSupportProvider> {
public static final LanguageRefactoringSupport INSTANCE = new LanguageRefactoringSupport();
private LanguageRefactoringSupport() {
- super("com.intellij.lang.refactoringSupport", new DefaultRefactoringSupportProvider());
+ super("com.intellij.lang.refactoringSupport", new RefactoringSupportProvider() {});
}
}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.intellij.lang.refactoring;
-
-import com.intellij.psi.PsiElement;
-import com.intellij.refactoring.RefactoringActionHandler;
-import com.intellij.refactoring.changeSignature.ChangeSignatureHandler;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Default implementation of <code>RefactoringSupportProvider</code> to inherit from
- */
-public class DefaultRefactoringSupportProvider implements RefactoringSupportProvider {
- public boolean isSafeDeleteAvailable(PsiElement element) {
- return false;
- }
-
- @Nullable
- public RefactoringActionHandler getIntroduceVariableHandler() {
- return null;
- }
-
- @Nullable
- public RefactoringActionHandler getExtractMethodHandler() {
- return null;
- }
-
- public RefactoringActionHandler getIntroduceConstantHandler() {
- return null;
- }
-
- public RefactoringActionHandler getIntroduceFieldHandler() {
- return null;
- }
-
- public RefactoringActionHandler getIntroduceParameterHandler() {
- return null;
- }
-
- public RefactoringActionHandler getPullUpHandler() {
- return null;
- }
-
- public RefactoringActionHandler getPushDownHandler() {
- return null;
- }
-
- public RefactoringActionHandler getExtractInterfaceHandler() {
- return null;
- }
-
- public RefactoringActionHandler getExtractModuleHandler() {
- return null;
- }
-
- public RefactoringActionHandler getExtractSuperClassHandler() {
- return null;
- }
-
- public boolean doInplaceRenameFor(final PsiElement element, final PsiElement context) {
- return false;
- }
-
- public ChangeSignatureHandler getChangeSignatureHandler() {
- return null;
- }
-}
*
* @author ven
*/
-
-public interface RefactoringSupportProvider {
+public abstract class RefactoringSupportProvider {
/**
* Checks if the Safe Delete refactoring can be applied to the specified element
* in the language. The Safe Delete refactoring also requires the plugin to implement
* @param element the element for which Safe Delete was invoked
* @return true if Safe Delete is available, false otherwise.
*/
- boolean isSafeDeleteAvailable(PsiElement element);
+ public boolean isSafeDeleteAvailable(PsiElement element) { return false; }
/**
* @return handler for introducing local variables in this language
* @see com.intellij.refactoring.RefactoringActionHandler
*/
- @Nullable RefactoringActionHandler getIntroduceVariableHandler();
+ @Nullable
+ public RefactoringActionHandler getIntroduceVariableHandler() { return null; }
/**
* @return handler for extracting methods in this language
* @see com.intellij.refactoring.RefactoringActionHandler
*/
- @Nullable RefactoringActionHandler getExtractMethodHandler();
+ @Nullable
+ public RefactoringActionHandler getExtractMethodHandler() { return null; }
/**
* @return handler for introducing constants in this language
* @see com.intellij.refactoring.RefactoringActionHandler
*/
- @Nullable RefactoringActionHandler getIntroduceConstantHandler();
+ @Nullable
+ public RefactoringActionHandler getIntroduceConstantHandler() { return null; }
/**
* @return handler for introducing fields in this language
* @see com.intellij.refactoring.RefactoringActionHandler
*/
- @Nullable RefactoringActionHandler getIntroduceFieldHandler();
+ @Nullable
+ public RefactoringActionHandler getIntroduceFieldHandler() { return null; }
/**
* @return handler for introducing parameters in this language
* @see com.intellij.refactoring.RefactoringActionHandler
*/
- @Nullable RefactoringActionHandler getIntroduceParameterHandler();
+ @Nullable
+ public RefactoringActionHandler getIntroduceParameterHandler() { return null; }
/**
* @return handler for pulling up members in this language
* @see com.intellij.refactoring.RefactoringActionHandler
*/
- @Nullable RefactoringActionHandler getPullUpHandler();
+ @Nullable
+ public RefactoringActionHandler getPullUpHandler() { return null; }
/**
* @return handler for pushing down members in this language
* @see com.intellij.refactoring.RefactoringActionHandler
*/
- @Nullable RefactoringActionHandler getPushDownHandler();
+ @Nullable
+ public RefactoringActionHandler getPushDownHandler() { return null; }
/**
* @return handler for extracting members to an interface in this language
* @see com.intellij.refactoring.RefactoringActionHandler
*/
- @Nullable RefactoringActionHandler getExtractInterfaceHandler();
+ @Nullable
+ public RefactoringActionHandler getExtractInterfaceHandler() { return null; }
/**
* @return handler for extracting members to some module in this language
* @see com.intellij.refactoring.RefactoringActionHandler
*/
- @Nullable RefactoringActionHandler getExtractModuleHandler();
+ @Nullable
+ public RefactoringActionHandler getExtractModuleHandler() { return null; }
/**
* @return handler for extracting super class in this language
* @see com.intellij.refactoring.RefactoringActionHandler
*/
- @Nullable RefactoringActionHandler getExtractSuperClassHandler();
+ @Nullable
+ public RefactoringActionHandler getExtractSuperClassHandler() { return null; }
/**
* @return handler for changing signature in this language
* @see com.intellij.refactoring.RefactoringActionHandler
*/
- @Nullable ChangeSignatureHandler getChangeSignatureHandler();
+ @Nullable
+ public ChangeSignatureHandler getChangeSignatureHandler() { return null; }
- boolean doInplaceRenameFor(PsiElement element, PsiElement context);
+ public boolean isInplaceRenameAvailable(PsiElement element, PsiElement context) { return false; }
}
--- /dev/null
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.usageView;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.refactoring.RefactoringBundle;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Dmitry Avdeev
+ */
+public class BaseUsageViewDescriptor implements UsageViewDescriptor {
+
+ private PsiElement[] myElements;
+
+ public BaseUsageViewDescriptor(PsiElement... elements) {
+ myElements = elements;
+ }
+
+ @NotNull
+ @Override
+ public PsiElement[] getElements() {
+ return myElements;
+ }
+
+ @Override
+ public String getProcessedElementsHeader() {
+ return "Element(s) to be refactored:";
+ }
+
+ @Override
+ public String getCodeReferencesText(int usagesCount, int filesCount) {
+ return RefactoringBundle.message("references.to.be.changed", UsageViewBundle.getReferencesString(usagesCount, filesCount));
+ }
+
+ @Nullable
+ @Override
+ public String getCommentReferencesText(int usagesCount, int filesCount) {
+ return null;
+ }
+}
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
public interface UsageViewDescriptor {
/**
String getCodeReferencesText(int usagesCount, int filesCount);
+ @Nullable
String getCommentReferencesText(int usagesCount, int filesCount);
}
\ No newline at end of file
boolean shown = false;
try {
- LogicalPosition pos = editor.xyToLogicalPosition(e.getMouseEvent().getPoint());
+ // There is a possible case that cursor is located at soft wrap-introduced virtual space (that is mapped to offset
+ // of the document symbol just after soft wrap). We don't want to show any tooltips for it then.
+ VisualPosition visual = editor.xyToVisualPosition(e.getMouseEvent().getPoint());
+ if (editor.getSoftWrapModel().isInsideSoftWrap(visual)) {
+ return;
+ }
+ LogicalPosition logical = editor.visualToLogicalPosition(visual);
if (e.getArea() == EditorMouseEventArea.EDITING_AREA) {
- int offset = editor.logicalPositionToOffset(pos);
- if (editor.offsetToLogicalPosition(offset).column != pos.column) return; // we are in virtual space
+ int offset = editor.logicalPositionToOffset(logical);
+ if (editor.offsetToLogicalPosition(offset).column != logical.column) return; // we are in virtual space
HighlightInfo info = myDaemonCodeAnalyzer.findHighlightByOffset(editor.getDocument(), offset, false);
if (info == null || info.description == null) return;
DaemonTooltipUtil.showInfoTooltip(info, editor, offset);
@NotNull final Template template,
boolean inSeparateCommand,
Map<String, String> predefinedVarValues,
- TemplateEditingListener listener);
+ @Nullable TemplateEditingListener listener);
public abstract void startTemplate(@NotNull Editor editor,
@NotNull Template template,
import com.intellij.psi.util.PsiElementFilter;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.containers.HashMap;
-import org.jetbrains.annotations.NonNls;
+import javax.swing.*;
import java.util.Map;
public class SaveAsTemplateAction extends AnAction {
- public static final @NonNls String JAVA_LANG_PACKAGE_PREFIX = "java.lang";
public void actionPerformed(AnActionEvent e) {
DataContext dataContext = e.getDataContext();
template.getTemplateContext().setEnabled(contextType, contextType.isInContext(fileType));
}
+ if (editTemplate(template, editor.getComponent(), true)) return;
+ templateSettings.addTemplate(template);
+ }
+
+ public static boolean editTemplate(TemplateImpl template, JComponent component, final boolean newTemplate) {
+
+ TemplateSettings templateSettings = TemplateSettings.getInstance();
String defaultShortcut = "";
if (templateSettings.getDefaultShortcutChar() == TemplateSettings.ENTER_CHAR) {
defaultShortcut = CodeInsightBundle.message("template.shortcut.enter");
Map<TemplateContextType, Boolean> context = template.createContext();
EditTemplateDialog dialog = new EditTemplateDialog(
- editor.getComponent(),
+ component,
CodeInsightBundle.message("dialog.edit.live.template.title"),
template,
templateSettings.getTemplateGroups(),
- defaultShortcut, options, context);
+ defaultShortcut, options, context, newTemplate);
dialog.show();
if (!dialog.isOK()) {
- return;
+ return true;
}
dialog.apply();
template.applyOptions(options);
template.applyContext(context);
- templateSettings.addTemplate(template);
templateSettings.setLastSelectedTemplateKey(template.getKey());
+ return false;
}
public void update(AnActionEvent e) {
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.ui.IdeBorderFactory;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
private static final String ENTER = CodeInsightBundle.message("template.shortcut.enter");
private final Map<TemplateOptionalProcessor, Boolean> myOptions;
private final Map<TemplateContextType, Boolean> myContext;
+ private final boolean myNewTemplate;
public EditTemplateDialog(Component parent, String title, TemplateImpl template, List<TemplateGroup> groups, String defaultShortcut,
- Map<TemplateOptionalProcessor, Boolean> options, Map<TemplateContextType, Boolean> context) {
+ Map<TemplateOptionalProcessor, Boolean> options,
+ Map<TemplateContextType, Boolean> context,
+ boolean newTemplate) {
super(parent, true);
myOptions = options;
myContext = context;
+ myNewTemplate = newTemplate;
setOKButtonText(CommonBundle.getOkButtonText());
setTitle(title);
myEditVariablesButton.setMaximumSize(myEditVariablesButton.getPreferredSize());
panel.add(myEditVariablesButton, gbConstraints);
- gbConstraints.weighty = 0;
- gbConstraints.gridwidth = 1;
- gbConstraints.gridy++;
- panel.add(createTemplateOptionsPanel(), gbConstraints);
+ JPanel templateOptionsPanel = createTemplateOptionsPanel();
+ JPanel contextPanel = createContextPanel();
+ if (myNewTemplate) {
+ gbConstraints.weighty = 0;
+ gbConstraints.gridwidth = 1;
+ gbConstraints.gridy++;
+ panel.add(templateOptionsPanel, gbConstraints);
- gbConstraints.gridx = 1;
- panel.add(createContextPanel(), gbConstraints);
+ gbConstraints.gridx = 1;
+ panel.add(contextPanel, gbConstraints);
+ }
myKeyField.getDocument().addDocumentListener(new com.intellij.ui.DocumentAdapter() {
protected void textChanged(javax.swing.event.DocumentEvent e) {
return panel;
}
+ @Nullable
protected JComponent createNorthPanel() {
+ if (!myNewTemplate) {
+ return null;
+ }
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbConstraints = new GridBagConstraints();
gbConstraints.insets = new Insets(4,4,4,4);
String oldGroupName = template.getGroupName();
EditTemplateDialog dialog = new EditTemplateDialog(this, CodeInsightBundle.message("dialog.edit.live.template.title"), template, getTemplateGroups(),
- (String)myExpandByCombo.getSelectedItem(), getOptions(template), getContext(template));
+ (String)myExpandByCombo.getSelectedItem(), getOptions(template), getContext(template), true);
dialog.show();
if (!dialog.isOK()) return;
myTemplateOptions.put(getKey(template), template.createOptions());
myTemplateContext.put(getKey(template), template.createContext());
EditTemplateDialog dialog = new EditTemplateDialog(this, CodeInsightBundle.message("dialog.add.live.template.title"), template, getTemplateGroups(),
- (String)myExpandByCombo.getSelectedItem(), getOptions(template), getContext(template));
+ (String)myExpandByCombo.getSelectedItem(), getOptions(template), getContext(template), true);
dialog.show();
if (!dialog.isOK()) return;
dialog.apply();
myTemplateOptions.put(getKey(template), getOptions(orTemplate));
myTemplateContext.put(getKey(template), getContext(orTemplate));
EditTemplateDialog dialog = new EditTemplateDialog(this, CodeInsightBundle.message("dialog.copy.live.template.title"), template, getTemplateGroups(),
- (String)myExpandByCombo.getSelectedItem(), getOptions(template), getContext(template));
+ (String)myExpandByCombo.getSelectedItem(), getOptions(template), getContext(template), true);
dialog.show();
if (!dialog.isOK()) return;
tlBlock.setParent(this);
}
- Block getOriginal() {
+ public Block getOriginal() {
return myOriginal;
}
*
* @param elements - refreshed elements that are returned by UsageViewDescriptor.getElements()
*/
- protected abstract void refreshElements(PsiElement[] elements);
+ protected void refreshElements(PsiElement[] elements) {}
/**
* Is called inside atomic action.
supportProvider = element != null ? LanguageRefactoringSupport.INSTANCE.forLanguage(element.getLanguage()):null;
return supportProvider != null &&
editor.getSettings().isVariableInplaceRenameEnabled() &&
- supportProvider.doInplaceRenameFor(element, nameSuggestionContext);
+ supportProvider.isInplaceRenameAvailable(element, nameSuggestionContext);
}
public final boolean isRenaming(final DataContext dataContext) {
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.UIBundle;
+import com.intellij.util.Consumer;
import com.intellij.util.ui.update.LazyUiDisposable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
fileChooserDescriptor.setDescription(myDescription);
}
VirtualFile initialFile = getInitialFile();
- VirtualFile[] files = doChoose(fileChooserDescriptor, initialFile);
- if (files != null && files.length != 0) {
- onFileChoosen(files[0]);
- }
+
+ FileChooser.chooseFilesWithSlideEffect(fileChooserDescriptor, myProject, initialFile, new Consumer<VirtualFile[]>() {
+ @Override
+ public void consume(VirtualFile[] virtualFiles) {
+ if (virtualFiles != null && virtualFiles.length > 0) {
+ onFileChoosen(virtualFiles[0]);
+ }
+ }
+ });
}
@Nullable
myAccessor.setText(myTextComponent.getChildComponent(), chosenFile.getPresentableUrl());
}
- private VirtualFile[] doChoose(FileChooserDescriptor fileChooserDescriptor, VirtualFile initialFile) {
- if (myProject == null) {
- return FileChooser.chooseFiles(myTextComponent, fileChooserDescriptor, initialFile);
- }
- else {
- return FileChooser.chooseFiles(myProject, fileChooserDescriptor, initialFile);
- }
- }
}
public final void requestFocus() {
import javax.swing.*;
import javax.swing.border.Border;
-import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import java.awt.*;
*/
public class TreeComboBox extends JComboBox {
final static int INDENT = UIManager.getInt("Tree.leftChildIndent");
+ private TreeModel myTreeModel;
public TreeComboBox(@NotNull final TreeModel model) {
- setModel(new TreeModelWrapper(model));
+ myTreeModel = model;
+ setModel(new TreeModelWrapper(myTreeModel));
setRenderer(new TreeListCellRenderer(this, model));
- setSelectedIndex(0);
if (SystemInfo.isMac) setMaximumRowCount(25);
}
+ public TreeModel getTreeModel() {
+ return myTreeModel;
+ }
+
private static class TreeListCellRenderer extends JLabel implements ListCellRenderer {
private static final Border SELECTION_PAINTER = (Border)UIManager.get("MenuItem.selectedBackgroundPainter");
--- /dev/null
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ui;
+
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkListener;
+
+/**
+ * @author Dmitry Avdeev
+ */
+public abstract class HyperlinkAdapter implements HyperlinkListener {
+
+ @Override
+ public void hyperlinkUpdate(HyperlinkEvent e) {
+ if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
+ hyperlinkActivated(e);
+ }
+ }
+
+ protected abstract void hyperlinkActivated(HyperlinkEvent e);
+}
import org.jetbrains.annotations.NonNls;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
Element action = (Element)iterator.next();
if (ELEMENT_TYPING.equals(action.getName())) {
Pair<List<Integer>, List<Integer>> codes = parseKeyCodes(action.getAttributeValue(ATTRIBUTE_KEY_CODES));
- myActions.add(new TypedDescriptor(action.getAttributeValue(ATTRIBUTE_TEXT), codes.getFirst(), codes.getSecond()));
+
+ String text = action.getText();
+ if (text == null || text.length() == 0) {
+ text = action.getAttributeValue(ATTRIBUTE_TEXT);
+ }
+
+ myActions.add(new TypedDescriptor(text, codes.getFirst(), codes.getSecond()));
}
else if (ELEMENT_ACTION.equals(action.getName())) {
myActions.add(new IdActionDescriptor(action.getAttributeValue(ATTRIBUTE_ID)));
actionNode = new Element(ELEMENT_TYPING);
TypedDescriptor typedDescriptor = (TypedDescriptor)action;
final String t = typedDescriptor.getText();
- actionNode.setAttribute(ATTRIBUTE_TEXT, JDOMUtil.escapeText(t));
+ actionNode.setText(t);
actionNode.setAttribute(ATTRIBUTE_KEY_CODES, unparseKeyCodes(new Pair<List<Integer>, List<Integer>>(typedDescriptor.getKeyCodes(), typedDescriptor.getKeyModifiers())));
}
else if (action instanceof IdActionDescriptor) {
@Override
public void run() {
if (finalLine >= 0) {
- myRightSide.scrollToFirstDiff(finalLine);
+ final int line = myLineBlocks.transform(myRightSide.getSide(), finalLine);
+ myLeftSide.scrollToFirstDiff(line);
} else {
scrollCurrentToFirstDiff();
}
@Override
public void run() {
final int startLine = myDocument.getLineNumber(textRange.getStartOffset());
- final int endLine = myDocument.getLineNumber(textRange.getEndOffset());
+ final int endFragmentOffset = textRange.getEndOffset();
+ final int endLine = myDocument.getLineNumber(endFragmentOffset);
for (int i = startLine; i <= endLine; i++) {
- String text = myDocument.getText().substring(myDocument.getLineStartOffset(i), myDocument.getLineEndOffset(i));
+ int lineEndOffset = myDocument.getLineEndOffset(i);
+ final int lineStartOffset = myDocument.getLineStartOffset(i);
+ if (lineEndOffset > endFragmentOffset && (endFragmentOffset == lineStartOffset)) {
+ lineEndOffset = endFragmentOffset;
+ }
+ if (lineStartOffset > lineEndOffset) continue;
+ String text = myDocument.getText().substring(lineStartOffset, lineEndOffset);
myBuffer.add(new Pair<Integer, String>(i, text));
}
}
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.actionSystem.EditorAction;
import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler;
+import com.intellij.openapi.editor.ex.util.EditorUtil;
+import com.intellij.openapi.util.Pair;
public class DuplicateAction extends EditorAction {
public DuplicateAction() {
private static void duplicateLineOrSelectedBlockAtCaret(Editor editor) {
Document document = editor.getDocument();
+ CaretModel caretModel = editor.getCaretModel();
+ ScrollingModel scrollingModel = editor.getScrollingModel();
if(editor.getSelectionModel().hasSelection()) {
int start = editor.getSelectionModel().getSelectionStart();
int end = editor.getSelectionModel().getSelectionEnd();
String s = document.getCharsSequence().subSequence(start, end).toString();
document.insertString(end, s);
- editor.getCaretModel().moveToOffset(end+s.length());
- editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
+ caretModel.moveToOffset(end+s.length());
+ scrollingModel.scrollToCaret(ScrollType.RELATIVE);
editor.getSelectionModel().removeSelection();
editor.getSelectionModel().setSelection(end, end+s.length());
}
else {
- VisualPosition caret = editor.getCaretModel().getVisualPosition();
- LogicalPosition lineStart = editor.visualToLogicalPosition(new VisualPosition(caret.line, 0));
- LogicalPosition nextLineStart = editor.visualToLogicalPosition(new VisualPosition(caret.line + 1, 0));
- if (nextLineStart.line == lineStart.line) {
- nextLineStart = new LogicalPosition(lineStart.line+1, 0);
- }
+ Pair<LogicalPosition, LogicalPosition> lines = EditorUtil.calcCaretLinesRange(editor);
+ int offset = caretModel.getOffset();
+ LogicalPosition lineStart = lines.first;
+ LogicalPosition nextLineStart = lines.second;
int start = editor.logicalPositionToOffset(lineStart);
int end = editor.logicalPositionToOffset(nextLineStart);
String s = document.getCharsSequence().subSequence(start, end).toString();
final int lineToCheck = nextLineStart.line - 1;
+ int newOffset = end + offset - start;
if(lineToCheck == document.getLineCount () /*empty document*/ ||
document.getLineSeparatorLength(lineToCheck) == 0) {
s = "\n"+s;
+ newOffset++;
}
document.insertString(end, s);
- editor.getCaretModel().moveCaretRelatively(0, 1, false, false, true);
+
+ caretModel.moveToOffset(newOffset);
+ scrollingModel.scrollToCaret(ScrollType.RELATIVE);
}
}
import com.intellij.openapi.editor.impl.ComplementaryFontsRegistry;
import com.intellij.openapi.editor.impl.FontInfo;
import com.intellij.openapi.editor.impl.IterationState;
+import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
int startToUse = start;
// Skip all lines except the last.
- for (int i = StringUtil.lastIndexOf(text, '\n', start, end); i >= 0; i = StringUtil.lastIndexOf(text, '\n', start, end)) {
+ for (int i = StringUtil.lastIndexOf(text, '\n', startToUse, end); i >= 0; i = StringUtil.lastIndexOf(text, '\n', startToUse, end)) {
startToUse = i + 1;
}
}
return result;
}
+
+ /**
+ * Calculates the closest non-soft-wrapped logical positions for current caret position.
+ *
+ * @param editor target editor to use
+ * @return pair of non-soft-wrapped logical positions closest to the caret position of the given editor
+ */
+ public static Pair<LogicalPosition, LogicalPosition> calcCaretLinesRange(Editor editor) {
+ VisualPosition caret = editor.getCaretModel().getVisualPosition();
+ int visualLine = caret.line;
+
+ LogicalPosition lineStart = editor.visualToLogicalPosition(new VisualPosition(visualLine, 0));
+ while (lineStart.softWrapLinesOnCurrentLogicalLine > 0) {
+ lineStart = editor.visualToLogicalPosition(new VisualPosition(--visualLine, 0));
+ }
+
+ visualLine = caret.line + 1;
+ LogicalPosition nextLineStart = editor.visualToLogicalPosition(new VisualPosition(caret.line + 1, 0));
+ while (nextLineStart.line == lineStart.line) {
+ nextLineStart = editor.visualToLogicalPosition(new VisualPosition(++visualLine, 0));
+ }
+ return new Pair<LogicalPosition, LogicalPosition>(lineStart, nextLineStart);
+ }
}
VerticalInfo oldInfo = myCaretInfo;
LogicalPosition oldCaretPosition = myLogicalCaret;
- setCurrentLogicalCaret(new LogicalPosition(
- line, column, softWrapLinesBefore, softWrapLinesCurrent, softWrapColumns, pos.foldedLines, pos.foldingColumnDiff
- ));
+ LogicalPosition logicalPositionToUse;
+ if (pos.visualPositionAware) {
+ logicalPositionToUse = new LogicalPosition(
+ line, column, softWrapLinesBefore, softWrapLinesCurrent, softWrapColumns, pos.foldedLines, pos.foldingColumnDiff
+ );
+ }
+ else {
+ logicalPositionToUse = new LogicalPosition(line, column);
+ }
+ setCurrentLogicalCaret(logicalPositionToUse);
final int offset = myEditor.logicalPositionToOffset(myLogicalCaret);
while (!iterationState.atEnd() && !lIterator.atEnd()) {
int hEnd = iterationState.getEndOffset();
int lEnd = lIterator.getEnd();
- getSoftWrapModel().registerSoftWrapIfNecessary(myDocument.getRawChars(), start, hEnd, position.x, fontType);
+ getSoftWrapModel().registerSoftWrapIfNecessary(text, start, hEnd, position.x, fontType);
if (hEnd >= lEnd) {
FoldRegion collapsedFolderAt = myFoldingModel.getCollapsedRegionAtOffset(start);
flushBackground(g, clip);
if (lIterator.getLineNumber() >= lastLineIndex && position.y <= clip.y + clip.height) {
- getSoftWrapModel().registerSoftWrapIfNecessary(myDocument.getRawChars(), start, myDocument.getTextLength(), position.x, fontType);
+ getSoftWrapModel().registerSoftWrapIfNecessary(text, start, myDocument.getTextLength(), position.x, fontType);
paintAfterFileEndBackground(iterationState, g, position, clip, lineHeight, defaultBackground, caretRowPainted);
}
import com.intellij.openapi.editor.event.SelectionListener;
import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.editor.ex.PrioritizedDocumentListener;
+import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
return;
}
- VisualPosition caret = myEditor.getCaretModel().getVisualPosition();
- LogicalPosition lineStart = myEditor.visualToLogicalPosition(new VisualPosition(caret.line, 0));
- LogicalPosition nextLineStart = myEditor.visualToLogicalPosition(new VisualPosition(caret.line + 1, 0));
+ Pair<LogicalPosition, LogicalPosition> lines = EditorUtil.calcCaretLinesRange(myEditor);
+ LogicalPosition lineStart = lines.first;
+ LogicalPosition nextLineStart = lines.second;
int start = myEditor.logicalPositionToOffset(lineStart);
int end = myEditor.logicalPositionToOffset(nextLineStart);
return result;
}
- public void registerSoftWrapIfNecessary(@NotNull char[] chars, int start, int end, int x, int fontType) {
+ public void registerSoftWrapIfNecessary(@NotNull CharSequence text, int start, int end, int x, int fontType) {
if (!isSoftWrappingEnabled()) {
return;
}
myActive++;
try {
- myApplianceManager.registerSoftWrapIfNecessary(chars, start, end, x, fontType);
+ myApplianceManager.registerSoftWrapIfNecessary(text, start, end, x, fontType);
}
finally {
myActive--;
return false;
}
- // We consider visual positions that point after the last symbol before soft wrap and the first symbol after soft wrap to not
- // belong to soft wrap-introduced virtual space.
+ // We consider visual position that points after the last symbol before soft wrap belong to soft wrap-introduced virtual space
+ // and visual position that points to the first document symbol after soft wrap not belong to soft wrap-introduced virtual space.
VisualPosition visualAfterSoftWrap = myEditor.offsetToVisualPosition(offset);
if (visualAfterSoftWrap.line == visual.line && visualAfterSoftWrap.column <= visual.column) {
return false;
}
int width = EditorUtil.textWidthInColumns(myEditor, myEditor.getDocument().getCharsSequence(), offset - 1, offset, columnOffset);
int softWrapStartColumn = visualBeforeSoftWrap.column + width;
- return visual.line > visualBeforeSoftWrap.line || visual.column > softWrapStartColumn;
+ return visual.line > visualBeforeSoftWrap.line || visual.column >= softWrapStartColumn;
}
@Override
@Override
public void beforeDocumentChange(DocumentEvent event) {
+ if (!isSoftWrappingEnabled()) {
+ return;
+ }
for (DocumentListener listener : myDocumentListeners) {
listener.beforeDocumentChange(event);
}
@Override
public void documentChanged(DocumentEvent event) {
+ if (!isSoftWrappingEnabled()) {
+ return;
+ }
for (DocumentListener listener : myDocumentListeners) {
listener.documentChanged(event);
}
import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
+import java.awt.*;
import java.nio.CharBuffer;
/**
}
private void dropData(int startLine, int endLine) {
+ Document document = myEditor.getDocument();
for (int i = startLine; i <= endLine; i++) {
myProcessedLogicalLines.remove(i);
+
+ // Calculate approximate soft wraps positions using plain font.
+ // Note: we don't update 'myProcessedLogicalLines' collection here, i.e. soft wraps will be recalculated precisely
+ // during standard editor repainting iteration.
+ if (i < document.getLineCount()) {
+ processLogicalLine(document.getCharsSequence(), i, Font.PLAIN, IndentType.NONE);
+ }
}
}
};
@SuppressWarnings({"AssignmentToForLoopParameter"})
@Override
- public void registerSoftWrapIfNecessary(@NotNull char[] chars, int start, int end, int x, int fontType) {
+ public void registerSoftWrapIfNecessary(@NotNull CharSequence text, int start, int end, int x, int fontType) {
dropDataIfNecessary();
- if (start >= end) {
+ if (myVisibleAreaWidth <= 0 || start >= end) {
return;
}
if (!myEditor.isViewer() && !document.isWritable()) {
indent = IndentType.TO_PREV_LINE_NON_WS_START;
}
- processLogicalLine(chars, i, fontType, indent);
+ processLogicalLine(text, i, fontType, indent);
myProcessedLogicalLines.add(i);
}
}
myVisibleAreaWidth = currentVisibleAreaWidth;
}
- private void processLogicalLine(char[] text, int line, int fontType, IndentType indentType) {
+ private void processLogicalLine(CharSequence text, int line, int fontType, IndentType indentType) {
Document document = myEditor.getDocument();
int startOffset = document.getLineStartOffset(line);
int endOffset = document.getLineEndOffset(line);
+ // There is a possible case that this method is called for the approximate soft wraps positions calculation. E.g. the
+ // user can insert a long string to the end of the document and we don't want to perform horizontal scrolling to its end.
+ // Hence, we approximately define soft wraps for the inserted text assuming that there precise calculation will be performed
+ // on regular editor repainting iteration. However, we need to drop all those temporary soft wraps registered for
+ // the same line before.
+ myStorage.removeInRange(startOffset, endOffset);
+
if (indentType == IndentType.NONE) {
TIntArrayList offsets = calculateSoftWrapOffsets(text, startOffset, endOffset, fontType, 0);
registerSoftWraps(offsets, 0);
}
@SuppressWarnings({"AssignmentToForLoopParameter"})
- private TIntArrayList calculateSoftWrapOffsets(char[] text, int start, int end, int fontType, int reservedWidth) {
+ private TIntArrayList calculateSoftWrapOffsets(CharSequence text, int start, int end, int fontType, int reservedWidth) {
TIntArrayList result = new TIntArrayList();
// Find offsets where soft wraps should be applied for the logical line in case of no indent usage.
* @param max max offset to use (inclusive)
* @return wrapping offset to use (given <code>'max'</code> value should be returned if no more suitable point is found)
*/
- private static int calculateSoftWrapOffset(char[] text, int preferred, int min, int max) {
+ private static int calculateSoftWrapOffset(CharSequence text, int preferred, int min, int max) {
// Try to find target offset that is not greater than preferred position.
for (int i = preferred; i > min; i--) {
- char c = text[i];
+ char c = text.charAt(i);
if (WHITE_SPACES.contains(c)) {
return i < preferred ? i + 1 : i;
// Don't wrap on the non-id symbol preceded by another non-id symbol. E.g. consider that we have a statement
// like 'foo(int... args)'. We don't want to wrap on the second or third dots then.
- if (i > min + 1 && !isIdSymbol(c) && !isIdSymbol(text[i - 1])) {
+ if (i > min + 1 && !isIdSymbol(c) && !isIdSymbol(text.charAt(i - 1))) {
continue;
}
if (SPECIAL_SYMBOLS_TO_WRAP_AFTER.contains(c)) {
// Don't wrap on a non-id symbol followed by non-id symbol, e.g. don't wrap between two pluses at i++.
// Also don't wrap before non-id symbol preceded by a space - wrap on space instead;
- if (!isIdSymbol(c) && (i < min + 2 || (isIdSymbol(text[i - 1]) && !WHITE_SPACES.contains(text[i - 1])))) {
+ if (!isIdSymbol(c) && (i < min + 2 || (isIdSymbol(text.charAt(i - 1)) && !WHITE_SPACES.contains(text.charAt(i - 1))))) {
return i;
}
}
// Try to find target offset that is greater than preferred position.
for (int i = preferred + 1; i < max; i++) {
- char c = text[i];
+ char c = text.charAt(i);
if (WHITE_SPACES.contains(c)) {
return i;
}
// Don't wrap on the non-id symbol preceded by another non-id symbol. E.g. consider that we have a statement
// like 'foo(int... args)'. We don't want to wrap on the second or third dots then.
- if (i < max - 1 && !isIdSymbol(c) && !isIdSymbol(text[i + 1]) && !isIdSymbol(text[i - 1])) {
+ if (i < max - 1 && !isIdSymbol(c) && !isIdSymbol(text.charAt(i + 1)) && !isIdSymbol(text.charAt(i - 1))) {
continue;
}
if (SPECIAL_SYMBOLS_TO_WRAP_BEFORE.contains(c)) {
}
// Don't wrap on a non-id symbol followed by non-id symbol, e.g. don't wrap between two pluses at i++;
- if (!isIdSymbol(c) && (i >= max || isIdSymbol(text[i + 1]))) {
+ if (!isIdSymbol(c) && (i >= max - 1 || isIdSymbol(text.charAt(i + 1)))) {
return i;
}
}
* Defines a callback that is invoked on request to draw target text fragment and that can register new soft wraps in order
* to correctly represent it.
* <p/>
- * Target text fragment to represent belongs to the given char array and lays at <code>[start; end)</code> interval.
+ * Target text fragment to represent belongs to the given char sequence and lays at <code>[start; end)</code> interval.
* <p/>
* Please note that it's possible for soft wrap to occur inside <code>[start; end)</code> region - e.g. there is a possible
* case that particular single token is too long and we want to split it.
* <p/>
* <b>Note:</b> it's assumed that this method is called only on editor repainting.
*
- * @param chars target text holder
+ * @param text target text holder
* @param start start offset of the token to process within the given char array (inclusive)
* @param end end offset of the token to process within the given char array (exclusive)
* @param x <code>'x'</code> coordinate within the given graphics buffer that will be used to start drawing the text
* @param fontType font type used for the target text fragment representation
*/
- void registerSoftWrapIfNecessary(@NotNull char[] chars, int start, int end, int x, int fontType);
+ void registerSoftWrapIfNecessary(@NotNull CharSequence text, int start, int end, int x, int fontType);
}
return removed;
}
+ /**
+ * Allows to remove all soft wraps registered at the current storage with offsets from <code>[start; end)</code> range if any.
+ *
+ * @param startOffset start offset to use (inclusive)
+ * @param endOffset end offset to use (exclusive)
+ */
+ public void removeInRange(int startOffset, int endOffset) {
+ int startIndex = getSoftWrapIndex(startOffset);
+ if (startIndex < 0) {
+ startIndex = -startIndex - 1;
+ }
+
+ if (startIndex >= myWraps.size()) {
+ return;
+ }
+
+ int endIndex = startIndex;
+ for (; endIndex < myWraps.size(); endIndex++) {
+ TextChangeImpl softWrap = myWraps.get(endIndex);
+ if (softWrap.getStart() >= endOffset) {
+ break;
+ }
+ }
+
+ if (endIndex > startIndex) {
+ myWraps.subList(startIndex, endIndex).clear();
+ notifyListenersAboutRemoval();
+ }
+ }
+
/**
* Removes all soft wraps registered at the current storage.
*/
import com.intellij.openapi.components.impl.stores.IProjectStore;
import com.intellij.openapi.project.Project;
+import com.intellij.util.messages.Topic;
import org.jetbrains.annotations.NotNull;
public interface ProjectEx extends Project {
+ interface ProjectSaved {
+ Topic<ProjectSaved> TOPIC = Topic.create("SaveProjectTopic", ProjectSaved.class, Topic.BroadcastDirection.NONE);
+ void saved(@NotNull final Project project);
+ }
@NotNull
IProjectStore getStateStore();
import org.picocontainer.defaults.ConstructorInjectionComponentAdapter;
import java.io.IOException;
-import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
LOG.info("Error saving project", e);
} finally {
mySavingInProgress.set(false);
+ ApplicationManager.getApplication().getMessageBus().syncPublisher(ProjectSaved.TOPIC).saved(this);
}
}
}
if (mySheetCallback != null) {
final Window activeWindow = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
- if (activeWindow != null && activeWindow instanceof Frame) {
- final String frameTitle = ((Frame)activeWindow).getTitle();
+ if (activeWindow != null) {
+ String activeWindowTitle = null;
+ if (activeWindow instanceof Frame) {
+ activeWindowTitle = ((Frame)activeWindow).getTitle();
+ } else if (activeWindow instanceof JDialog) {
+ activeWindowTitle = ((JDialog)activeWindow).getTitle();
+ }
+ if (activeWindowTitle == null || activeWindowTitle.length() == 0) return;
final ID sharedApplication = invoke("NSApplication", "sharedApplication");
final ID windows = invoke(sharedApplication, "windows");
final ID windowTitle = invoke(window, "title");
final String titleString = Foundation.toStringViaUTF8(windowTitle);
- if (titleString.equals(frameTitle)) focusedWindow = window;
+ if (titleString.equals(activeWindowTitle)) {
+ focusedWindow = window;
+ break;
+ }
}
if (focusedWindow != null) {
*/
package com.intellij.util.ui;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.util.Disposer;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.table.TableView;
import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.table.TableCellEditor;
+import javax.swing.text.Document;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.util.EventObject;
public abstract class ChangesTrackingTableView<T> extends TableView<T> {
- private DocumentAdapter myMessageUpdater;
+ private Disposable myEditorListenerDisposable;
- protected abstract void onTextChanged(int row, int column, String value);
+ protected abstract void onCellValueChanged(int row, int column, Object value);
protected abstract void onEditingStopped();
@Override
public boolean editCellAt(final int row, final int column, EventObject e) {
if (super.editCellAt(row, column, e)) {
- assert myMessageUpdater == null;
- final JTextField textField;
- if (getEditorComponent() instanceof CellEditorComponentWithBrowseButton) {
- textField = (JTextField)((CellEditorComponentWithBrowseButton)editorComp).getChildComponent();
- }
- else {
- textField = (JTextField)getEditorComponent();
- }
- myMessageUpdater = new DocumentAdapter() {
+ assert myEditorListenerDisposable == null;
+ myEditorListenerDisposable = new Disposable() {
@Override
- protected void textChanged(DocumentEvent e) {
- onTextChanged(row, column, textField.getText());
+ public void dispose() {
}
};
- textField.getDocument().addDocumentListener(myMessageUpdater);
+ addChangeListener(getEditorComponent(), new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ onCellValueChanged(row, column, getValue(getEditorComponent()));
+ }
+ }, myEditorListenerDisposable);
return true;
}
return false;
@Override
public void removeEditor() {
- if (myMessageUpdater != null) {
- final JTextField textField;
- if (getEditorComponent() instanceof CellEditorComponentWithBrowseButton) {
- textField = (JTextField)((CellEditorComponentWithBrowseButton)editorComp).getChildComponent();
- }
- else {
- textField = (JTextField)getEditorComponent();
- }
- textField.getDocument().removeDocumentListener(myMessageUpdater);
- myMessageUpdater = null;
+ if (myEditorListenerDisposable != null) {
+ Disposer.dispose(myEditorListenerDisposable);
+ myEditorListenerDisposable = null;
}
onEditingStopped();
super.removeEditor();
}
-}
+
+ public static Object getValue(Component component) {
+ if (component instanceof CellEditorComponentWithBrowseButton) {
+ final JTextField textField = (JTextField)((CellEditorComponentWithBrowseButton)component).getChildComponent();
+ return textField.getText();
+ }
+ else if (component instanceof JTextField) {
+ return ((JTextField)component).getText();
+ }
+ else if (component instanceof JComboBox) {
+ return ((JComboBox)component).getSelectedItem();
+ }
+ throw new UnsupportedOperationException("editor control of type " + component.getClass().getName() + " is not supported");
+ }
+
+ private static void addChangeListener(final Component component, final ChangeListener listener, Disposable parentDisposable) {
+ if (component instanceof CellEditorComponentWithBrowseButton) {
+ addChangeListener(((CellEditorComponentWithBrowseButton)component).getChildComponent(), listener, parentDisposable);
+ }
+ else if (component instanceof JTextField) {
+ final DocumentAdapter documentListener = new DocumentAdapter() {
+ @Override
+ protected void textChanged(DocumentEvent e) {
+ listener.stateChanged(new ChangeEvent(component));
+ }
+ };
+ final Document document = ((JTextField)component).getDocument();
+ document.addDocumentListener(documentListener);
+ Disposer.register(parentDisposable, new Disposable() {
+ @Override
+ public void dispose() {
+ document.removeDocumentListener(documentListener);
+ }
+ });
+ }
+ else if (component instanceof JComboBox) {
+ final ActionListener comboListener = new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ listener.stateChanged(new ChangeEvent(component));
+ }
+ };
+ ((JComboBox)component).addActionListener(comboListener);
+ Disposer.register(parentDisposable, new Disposable() {
+ @Override
+ public void dispose() {
+ ((JComboBox)component).removeActionListener(comboListener);
+ }
+ });
+ }
+ else {
+ throw new UnsupportedOperationException("editor control of type " + component.getClass().getName() + " is not supported");
+ }
+ }
+
+}
\ No newline at end of file
String getTitle();
}
- private class ColumnInfoWrapper extends ColumnInfo<Item, String> {
- private final ColumnInfo<Item, String> myDelegate;
+ private class ColumnInfoWrapper extends ColumnInfo<Item, Object> {
+ private final ColumnInfo<Item, Object> myDelegate;
- public ColumnInfoWrapper(ColumnInfo<Item, String> delegate) {
+ public ColumnInfoWrapper(ColumnInfo<Item, Object> delegate) {
super(delegate.getName());
myDelegate = delegate;
}
@Override
- public String valueOf(Item item) {
+ public Object valueOf(Item item) {
return myDelegate.valueOf(item);
}
}
@Override
- public void setValue(Item item, String value) {
+ public void setValue(Item item, Object value) {
myDelegate.setValue(item, value);
updateMessage(-1, null);
}
public TableCellEditor getEditor(Item item) {
return myDelegate.getEditor(item);
}
+
+ @Override
+ public int getWidth(JTable table) {
+ return myDelegate.getWidth(table);
+ }
}
private JPanel myContentPane;
private void createUIComponents() {
myTable = new ChangesTrackingTableView<Item>() {
- protected void onTextChanged(int row, int column, String value) {
+ protected void onCellValueChanged(int row, int column, Object value) {
final Item original = getItems().get(row);
Item override = cloneOf(original);
- final ColumnInfo<Item, String> columnInfo = getTableModel().getColumnInfos()[column];
+ final ColumnInfo<Item, Object> columnInfo = getTableModel().getColumnInfos()[column];
columnInfo.setValue(override, value);
updateMessage(row, override);
}
return (ListTableModel<Item>)myTable.getModel();
}
- public void setModel(ColumnInfo<Item, String>[] valueColumns, List<Item> items) {
+ public void setModel(ColumnInfo<Item, Object>[] valueColumns, List<Item> items) {
ColumnInfo[] columns = new ColumnInfo[valueColumns.length + 1];
IconColumn iconColumn = new IconColumn();
int maxHeight = iconColumn.getRowHeight();
private List<Item> doGetItems() {
List<Item> items = new ArrayList<Item>(getTableModel().getItems());
if (myTable.isEditing()) {
- Component c = myTable.getEditorComponent();
- final JTextField textField;
- if (c instanceof CellEditorComponentWithBrowseButton) {
- textField = (JTextField)((CellEditorComponentWithBrowseButton)c).getChildComponent();
- }
- else {
- textField = (JTextField)c;
- }
- String value = textField.getText();
+ Object value = ChangesTrackingTableView.getValue(myTable.getEditorComponent());
ColumnInfo column = ((ListTableModel)myTable.getModel()).getColumnInfos()[myTable.getEditingColumn()];
((ColumnInfoWrapper)column).myDelegate.setValue(items.get(myTable.getEditingRow()), value);
}
current.set(index, override);
}
- Pair<String, Fix> messageAndFix = validate(current, myWarnings);
+ displayMessageAndFix(validate(current, myWarnings));
+ myTable.repaint();
+ }
+
+ protected void displayMessageAndFix(@Nullable Pair<String, Fix> messageAndFix) {
if (messageAndFix != null) {
myMessageLabel.setText(messageAndFix.first);
myMessageLabel.setIcon(WARNING_ICON);
myFixLink.setVisible(false);
myFixRunnable = null;
}
- myTable.repaint();
+ }
+
+ public void hideMessageLabel() {
+ myMessageLabel.setVisible(false);
+ myFixLink.setVisible(false);
}
public JComponent getPreferredFocusedComponent() {
return myContentPane;
}
+ public void setColumnReorderingAllowed(boolean value) {
+ JTableHeader header = myTable.getTableHeader();
+ if (header != null) {
+ header.setReorderingAllowed(value);
+ }
+ }
}
// Storage.
allowing(myStorage).removeAll();
+ allowing(myStorage).removeInRange(with(any(int.class)), with(any(int.class)));
// Soft wrap drawings.
allowing(myPainter).getMinDrawingWidth(with(any(SoftWrapDrawingType.class))); will(returnValue(SOFT_WRAP_DRAWING_SIZE));
allowing(myScrollingModel).getVisibleArea(); will(returnValue(new Rectangle(0, 0, context.visualWidth, Integer.MAX_VALUE)));
allowing(myDocument).getLineEndOffset(0); will(returnValue(context.document.length()));
}});
- char[] documentChars = context.document.toCharArray();
- myManager.registerSoftWrapIfNecessary(documentChars, 0, documentChars.length, 0, Font.PLAIN);
+ myManager.registerSoftWrapIfNecessary(context.document, 0, context.document.length(), 0, Font.PLAIN);
}
private static TextChangeImpl createSoftWrap(int offset, int indent) {
text="Add Test Notification"/>
<action id="TestMessageBoxAction" internal="true" class="com.intellij.diagnostic.TestMessageBoxAction" text="Show Test Dialog"/>
<separator/>
+ <action id="FocusDebugger" internal="true" class="com.intellij.internal.focus.FocusDebuggerAction" text="Start Focus Debugger"/>
+ <action id="UiInspector" internal="true" class="com.intellij.internal.inspector.UiInspectorAction" text="UI Inspector"/>
+ <separator/>
<reference ref="MaintenanceGroup"/>
-
+
<add-to-group group-id="ToolsMenu" anchor="last"/>
</group>
import com.intellij.util.text.CharArrayCharSequence;
import gnu.trove.Equality;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Array;
import java.util.Collection;
return (E[])Array.newInstance(sample.getClass().getComponentType(), count);
}
+
+ @Nullable
+ public static <T> T getLastElement(T[] array) {
+ return array.length > 0 ? array[array.length -1] : null;
+ }
}
myFileAnnotation = fileAnnotation;
myVcs = vcs;
myFile = file;
- final CommittedChangesProvider provider = myVcs.getCommittedChangesProvider();
currentLine = -1;
}
private DiffNavigationContext createDiffNavigationContext(final int actualLine) {
final MyContentsLines contentsLines = new MyContentsLines(myFileAnnotation.getAnnotatedContent());
+ final Pair<Integer, String> pair = correctActualLineIfTextEmpty(contentsLines, actualLine);
return new DiffNavigationContext(new Iterable<String>() {
@Override
public Iterator<String> iterator() {
- return new CacheOneStepIterator<String>(new ContextLineIterator(contentsLines, myFileAnnotation, actualLine));
+ return new CacheOneStepIterator<String>(new ContextLineIterator(contentsLines, myFileAnnotation, pair.getFirst()));
}
- }, contentsLines.getLineContents(actualLine));
+ }, pair.getSecond());
+ }
+
+ private final static int ourVicinity = 5;
+ private Pair<Integer, String> correctActualLineIfTextEmpty(final MyContentsLines contentsLines, final int actualLine) {
+ final VcsRevisionNumber revision = myFileAnnotation.getLineRevisionNumber(actualLine);
+
+ for (int i = actualLine; (i < (actualLine + ourVicinity)) && (! contentsLines.isLineEndsFinished()); i++) {
+ if (! revision.equals(myFileAnnotation.getLineRevisionNumber(i))) continue;
+ final String lineContents = contentsLines.getLineContents(i);
+ if (! StringUtil.isEmptyOrSpaces(lineContents)) {
+ return new Pair<Integer, String>(i, lineContents);
+ }
+ }
+ int bound = Math.max(actualLine - ourVicinity, 0);
+ for (int i = actualLine - 1; (i >= bound); --i) {
+ if (! revision.equals(myFileAnnotation.getLineRevisionNumber(i))) continue;
+ final String lineContents = contentsLines.getLineContents(i);
+ if (! StringUtil.isEmptyOrSpaces(lineContents)) {
+ return new Pair<Integer, String>(i, lineContents);
+ }
+ }
+ return new Pair<Integer, String>(actualLine, contentsLines.getLineContents(actualLine));
}
private static class MySplittingIterator implements Iterator<Integer> {
(number + 1 >= myLinesStartOffsets.size())
? myContents.length()
: myLinesStartOffsets.get(number + 1));
- text = text.endsWith("\r\n") ? text.substring(0, text.length() - 2) : text.substring(0, text.length() - 1);
+ text = text.endsWith("\r\n") ? text.substring(0, text.length() - 2) : text;
+ text = (text.endsWith("\r") || text.endsWith("\n")) ? text.substring(0, text.length() - 1) : text;
return text;
}
+ public boolean isLineEndsFinished() {
+ return myLineEndsFinished;
+ }
+
public int getKnownLinesNumber() {
return myLineEndsFinished ? myLinesStartOffsets.size() : -1;
}
}
if (DiffPresentationReturnValue.removeFromList.equals(returnValue)) {
mySteps.remove(nextIdx);
+ if (moveDirection.direction() < 0) {
+ // our position moves to head
+ myIndex += moveDirection.direction();
+ }
continue;
}
final DiffRequest request = result.getRequest();
private void update(@NotNull final Icon icon, @Nullable final String toolTipText) {
myCurrentIcon = icon;
myToolTipText = toolTipText;
+ myStatusBar.updateWidget(ID());
}
@NotNull
@Nullable
public HandleType createHandleType(final VirtualFile file) {
+ if (! myProject.isInitialized()) return null;
AbstractVcs vcs = ProjectLevelVcsManager.getInstance(myProject).getVcsFor(file);
if (vcs != null) {
boolean fileExistsInVcs = vcs.fileExistsInVcs(new FilePathImpl(file));
package com.intellij.platform;
import com.intellij.openapi.components.ProjectComponent;
+import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.vcs.AbstractVcs;
}
public void projectOpened() {
- StartupManager.getInstance(myProject).registerStartupActivity(new Runnable() {
+ StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new DumbAwareRunnable() {
public void run() {
VirtualFile file = ProjectBaseDirectory.getInstance(myProject).getBaseDir(myProject.getBaseDir());
AbstractVcs vcs = myVcsManager.findVersioningVcs(file);
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.Trinity;
+import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.util.xml.GenericAttributeValue;
import org.jetbrains.annotations.Nullable;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
public class AntBuildModelImpl implements AntBuildModelBase {
public String getDefaultTargetName() {
final AntDomProject antDomProject = getAntProject();
if (antDomProject != null) {
- final Trinity<AntDomTarget,String,Map<String,AntDomTarget>> defTarget = antDomProject.getDefaultTarget().getValue();
- if (defTarget != null) {
- return defTarget.getSecond();
+ final GenericAttributeValue<TargetResolver.Result> attrib = antDomProject.getDefaultTarget();
+ final TargetResolver.Result result = attrib.getValue();
+ if (result != null) {
+ final Pair<AntDomTarget,String> targetWithName = result.getResolvedTarget(attrib.getRawText());
+ return targetWithName != null? targetWithName.getSecond() : null;
}
}
return "";
}
myProcessed.add(sourceFile);
if (!myIsImported) {
- final GenericAttributeValue<Trinity<AntDomTarget,String,Map<String,AntDomTarget>>> defTarget = project.getDefaultTarget();
- if (defTarget != null) {
- final Trinity<AntDomTarget, String, Map<String, AntDomTarget>> trinity = defTarget.getValue();
- if (trinity != null) {
- myDefaultTarget = trinity.getFirst();
- }
+ final TargetResolver.Result result = project.getDefaultTarget().getValue();
+ if (result != null) {
+ final Pair<AntDomTarget,String> targetWithName = result.getResolvedTarget(project.getDefaultTarget().getRawText());
+ myDefaultTarget = targetWithName != null? targetWithName.getFirst() : null;
}
}
for (final AntDomTarget target : project.getDeclaredTargets()) {
*/
package com.intellij.lang.ant.dom;
-import com.intellij.openapi.util.Trinity;
import com.intellij.util.xml.Attribute;
import com.intellij.util.xml.Convert;
import com.intellij.util.xml.GenericAttributeValue;
import com.intellij.util.xml.SubTagList;
import java.util.List;
-import java.util.Map;
/**
* @author Eugene Zhuravlev
@Attribute("target")
@Convert(value = AntDomDefaultTargetConverter.class)
- public abstract GenericAttributeValue<Trinity<AntDomTarget, String, Map<String, AntDomTarget>>> getTarget();
+ public abstract GenericAttributeValue<TargetResolver.Result> getTarget();
@Attribute("inheritall")
@Convert(value = AntBooleanConverterDefaultTrue.class)
*/
package com.intellij.lang.ant.dom;
-import com.intellij.lang.ant.AntBundle;
import com.intellij.lang.ant.AntSupport;
-import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.util.Trinity;
-import com.intellij.pom.references.PomService;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.xml.*;
+import com.intellij.util.xml.ConvertContext;
+import com.intellij.util.xml.Converter;
+import com.intellij.util.xml.CustomReferenceConverter;
+import com.intellij.util.xml.GenericDomValue;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.Map;
-import java.util.Set;
-
/**
* @author Eugene Zhuravlev
* Date: Apr 16, 2010
*/
-public class AntDomDefaultTargetConverter extends Converter<Trinity<AntDomTarget, String, Map<String, AntDomTarget>>> implements CustomReferenceConverter<Trinity<AntDomTarget, String, Map<String, AntDomTarget>>>{
-
- @NotNull public PsiReference[] createReferences(final GenericDomValue<Trinity<AntDomTarget, String, Map<String, AntDomTarget>>> value, PsiElement element, ConvertContext context) {
- return new PsiReference[] {new AntDomReferenceBase(element, true) {
- public PsiElement resolve() {
- final Trinity<AntDomTarget, String, Map<String, AntDomTarget>> trinity = value.getValue();
- if (trinity == null) {
- return null;
- }
- final DomTarget domTarget = trinity.getFirst() != null? DomTarget.getTarget(trinity.getFirst()) : null;
- return domTarget != null? PomService.convertToPsi(domTarget) : null;
- }
+public class AntDomDefaultTargetConverter extends Converter<TargetResolver.Result> implements CustomReferenceConverter<TargetResolver.Result>{
- @NotNull
- public Object[] getVariants() {
- final Trinity<AntDomTarget, String, Map<String, AntDomTarget>> trinity = value.getValue();
- if (trinity == null) {
- return ArrayUtil.EMPTY_OBJECT_ARRAY;
- }
- final Set<String> set = trinity.getThird().keySet();
- return set.toArray(new Object[set.size()]);
- }
-
- public String getUnresolvedMessagePattern() {
- return AntBundle.message("cannot.resolve.target", getCanonicalText());
- }
- }};
+ @NotNull
+ public PsiReference[] createReferences(final GenericDomValue<TargetResolver.Result> value, PsiElement element, ConvertContext context) {
+ return new PsiReference[] {new AntDomTargetReference(element)};
}
@Nullable
- public Trinity<AntDomTarget, String, Map<String, AntDomTarget>> fromString(@Nullable @NonNls String s, ConvertContext context) {
+ public TargetResolver.Result fromString(@Nullable @NonNls String s, ConvertContext context) {
final AntDomElement element = AntSupport.getInvocationAntDomElement(context);
if (element != null && s != null) {
final AntDomProject project = element.getAntProject();
final TargetResolver.Result result = TargetResolver.resolve(project.getContextAntProject(), null, s);
- final Pair<AntDomTarget,String> pair = result.getResolvedTarget(s);
- return new Trinity<AntDomTarget, String, Map<String, AntDomTarget>>(pair != null? pair.getFirst() : null, pair != null? pair.getSecond() : null, result.getVariants());
+ result.setRefsString(s);
+ return result;
}
return null;
}
@Nullable
- public String toString(@Nullable Trinity<AntDomTarget, String, Map<String, AntDomTarget>> trinity, ConvertContext context) {
- return trinity != null? trinity.getSecond() : null;
+ public String toString(@Nullable TargetResolver.Result result, ConvertContext context) {
+ return result != null? result.getRefsString() : null;
}
+
}
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.SystemInfo;
-import com.intellij.openapi.util.Trinity;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.references.PomService;
@Attribute("default")
@Convert(value = AntDomDefaultTargetConverter.class)
- public abstract GenericAttributeValue<Trinity<AntDomTarget, String, Map<String, AntDomTarget>>> getDefaultTarget();
+ public abstract GenericAttributeValue<TargetResolver.Result> getDefaultTarget();
@Attribute("basedir")
@Convert(value = AntPathConverter.class)
*/
package com.intellij.lang.ant.dom;
-import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
-import com.intellij.codeInsight.lookup.LookupElement;
-import com.intellij.codeInsight.lookup.LookupElementBuilder;
-import com.intellij.lang.ant.AntBundle;
-import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
-import com.intellij.pom.references.PomService;
import com.intellij.psi.ElementManipulators;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlElement;
import com.intellij.util.text.StringTokenizer;
-import com.intellij.util.xml.*;
+import com.intellij.util.xml.ConvertContext;
+import com.intellij.util.xml.Converter;
+import com.intellij.util.xml.CustomReferenceConverter;
+import com.intellij.util.xml.GenericDomValue;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
/**
* @author Eugene Zhuravlev
if (valueElement == null) {
return PsiReference.EMPTY_ARRAY;
}
- final TargetResolver.Result result = value.getValue();
- if (result == null) {
+ final String refsString = value.getStringValue();
+ if (refsString == null) {
return PsiReference.EMPTY_ARRAY;
}
final List<PsiReference> refs = new ArrayList<PsiReference>();
- final StringTokenizer tokenizer = new StringTokenizer(result.getRefsString(), ",", false);
final TextRange wholeStringRange = ElementManipulators.getValueTextRange(valueElement);
- final Set<String> existingRefs = new HashSet<String>();
- final AntDomTarget hostAntTarget = context.getInvocationElement().getParentOfType(AntDomTarget.class, false);
- if (hostAntTarget != null) {
- existingRefs.add(hostAntTarget.getName().getRawText()); // avoid setting dependencies onto itself
- }
+ final StringTokenizer tokenizer = new StringTokenizer(refsString, ",", false);
while (tokenizer.hasMoreTokens()) {
final String token = tokenizer.nextToken();
int tokenStartOffset = tokenizer.getCurrentPosition() - token.length();
}
}
}
- final Pair<AntDomTarget,String> antTarget = result.getResolvedTarget(ref);
- final DomTarget domTarget = (antTarget != null && antTarget.getFirst() != null) ? DomTarget.getTarget(antTarget.getFirst()) : null;
- if (domTarget != null) {
- existingRefs.add(antTarget.getSecond());
- }
- refs.add(new AntDomReferenceBase(valueElement, TextRange.from(wholeStringRange.getStartOffset() + tokenStartOffset, ref.length()), true) {
- public PsiElement resolve() {
- return domTarget != null? PomService.convertToPsi(domTarget) : null;
- }
- @NotNull
- public Object[] getVariants() {
- final List<Object> variants = new ArrayList<Object>();
- for (Map.Entry<String, AntDomTarget> entry : result.getVariants().entrySet()) {
- final String targetEffectiveName = entry.getKey();
- if (!existingRefs.contains(targetEffectiveName)) {
- //final AntDomTarget target = entry.getValue();
- //final DomTarget _target = DomTarget.getTarget(target);
- //if (_target == null) {
- // continue;
- //}
- //final PsiElement psi = PomService.convertToPsi(_target);
- //if (psi == null) {
- // continue;
- //}
- final LookupElementBuilder builder = LookupElementBuilder.create(/*psi, */targetEffectiveName);
- final LookupElement element = AutoCompletionPolicy.GIVE_CHANCE_TO_OVERWRITE.applyPolicy(builder);
- variants.add(element);
- }
- }
- return variants.toArray();
- }
-
- public String getUnresolvedMessagePattern() {
- return AntBundle.message("cannot.resolve.target", getCanonicalText());
- }
- });
+ refs.add(new AntDomTargetReference(element, TextRange.from(wholeStringRange.getStartOffset() + tokenStartOffset, ref.length())));
}
return refs.toArray(new PsiReference[refs.size()]);
}
--- /dev/null
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.ant.dom;
+
+import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.lang.ant.AntBundle;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.pom.PomTarget;
+import com.intellij.pom.PomTargetPsiElement;
+import com.intellij.pom.references.PomService;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.impl.PsiManagerEx;
+import com.intellij.psi.impl.source.resolve.ResolveCache;
+import com.intellij.refactoring.rename.BindablePsiReference;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.ArrayListSet;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.text.StringTokenizer;
+import com.intellij.util.xml.DomElement;
+import com.intellij.util.xml.DomTarget;
+import com.intellij.util.xml.DomUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+* @author Eugene Zhuravlev
+* Date: Aug 17, 2010
+*/
+class AntDomTargetReference extends AntDomReferenceBase implements BindablePsiReference{
+
+ public AntDomTargetReference(PsiElement element) {
+ super(element, true);
+ }
+
+ public AntDomTargetReference(PsiElement element, TextRange range) {
+ super(element, range, true);
+ }
+
+ public PsiElement resolve() {
+ return ((PsiManagerEx)getElement().getManager()).getResolveCache().resolveWithCaching(this, MyResolver.INSTANCE, false, false);
+ }
+
+ public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
+ final DomElement targetDomElement = toDomElement(element);
+ if (targetDomElement != null) {
+ final AntDomTarget pointingToTarget = targetDomElement.getParentOfType(AntDomTarget.class, false);
+ if (pointingToTarget != null) {
+ // the aim here is to receive all variants available at this particular context
+ final TargetResolver.Result result = doResolve(null);
+ if (result != null) {
+ final Map<String, AntDomTarget> variants = result.getVariants();
+ for (Map.Entry<String, AntDomTarget> entry : variants.entrySet()) {
+ if (pointingToTarget.equals(entry.getValue())) {
+ handleElementRename(entry.getKey());
+ break;
+ }
+ }
+ }
+ }
+ }
+ return getElement();
+ }
+
+ @Nullable
+ private AntDomElement getHostingAntDomElement() {
+ final DomElement selfElement = DomUtil.getDomElement(getElement());
+ if (selfElement == null) {
+ return null;
+ }
+ return selfElement.getParentOfType(AntDomElement.class, false);
+ }
+
+ @Nullable
+ public static DomElement toDomElement(PsiElement resolve) {
+ if (resolve instanceof PomTargetPsiElement) {
+ final PomTarget target = ((PomTargetPsiElement)resolve).getTarget();
+ if(target instanceof DomTarget) {
+ return ((DomTarget)target).getDomElement();
+ }
+ return null;
+ }
+ return DomUtil.getDomElement(resolve);
+ }
+
+ @NotNull
+ public Object[] getVariants() {
+ final TargetResolver.Result result = doResolve(getCanonicalText());
+ if (result == null) {
+ return EMPTY_ARRAY;
+ }
+ final Map<String, AntDomTarget> variants = result.getVariants();
+ final List resVariants = new ArrayList();
+ final Set<String> existing = getExistingNames();
+ for (String s : variants.keySet()) {
+ if (existing.contains(s)){
+ continue;
+ }
+ final LookupElementBuilder builder = LookupElementBuilder.create(s);
+ final LookupElement element = AutoCompletionPolicy.GIVE_CHANCE_TO_OVERWRITE.applyPolicy(builder);
+ resVariants.add(element);
+ }
+ return ContainerUtil.toArray(resVariants, new Object[resVariants.size()]);
+ }
+
+ @Nullable
+ private TargetResolver.Result doResolve(@Nullable final String referenceText) {
+ final AntDomElement hostingElement = getHostingAntDomElement();
+ if (hostingElement == null) {
+ return null;
+ }
+ final AntDomTarget contextTarget = hostingElement.getParentOfType(AntDomTarget.class, false);
+ return TargetResolver.resolve(hostingElement.getContextAntProject(), contextTarget, referenceText == null? Collections.<String>emptyList() : Collections.singletonList(referenceText));
+ }
+
+ private Set<String> getExistingNames() {
+ final AntDomElement hostingElement = getHostingAntDomElement();
+ if (hostingElement == null) {
+ return Collections.emptySet();
+ }
+ final AntDomTarget contextTarget = hostingElement.getParentOfType(AntDomTarget.class, false);
+ if (contextTarget == null) {
+ return Collections.emptySet();
+ }
+ final Set<String> existing = new ArrayListSet<String>();
+ final String selfName = contextTarget.getName().getStringValue();
+ if (selfName != null) {
+ existing.add(selfName);
+ }
+ final String dependsString = contextTarget.getDependsList().getStringValue();
+ if (dependsString != null) {
+ final StringTokenizer tokenizer = new StringTokenizer(dependsString, ",", false);
+ while (tokenizer.hasMoreTokens()) {
+ existing.add(tokenizer.nextToken().trim());
+ }
+ }
+ return existing;
+ }
+
+ public String getUnresolvedMessagePattern() {
+ return AntBundle.message("cannot.resolve.target", getCanonicalText());
+ }
+
+ private static class MyResolver implements ResolveCache.Resolver {
+ static final MyResolver INSTANCE = new MyResolver();
+
+ public PsiElement resolve(PsiReference psiReference, boolean incompleteCode) {
+ final TargetResolver.Result result = ((AntDomTargetReference)psiReference).doResolve(psiReference.getCanonicalText());
+ if (result == null) {
+ return null;
+ }
+ final Pair<AntDomTarget,String> pair = result.getResolvedTarget(psiReference.getCanonicalText());
+ final DomTarget domTarget = pair != null && pair.getFirst() != null ? DomTarget.getTarget(pair.getFirst()) : null;
+ return domTarget != null? PomService.convertToPsi(domTarget) : null;
+ }
+ }
+}
private Map<String, List<String>> myDependenciesMap = new HashMap<String, List<String>>(); // target effective name -> dependencies effective names
private Set<String> myProcessedTargets = new HashSet<String>();
+ private Set<AntDomProject> myVisitedProjects = new HashSet<AntDomProject>();
protected PropertyProviderFinder(DomElement contextElement) {
myContextElement = contextElement != null? contextElement.getParentOfType(AntDomElement.class, false) : null;
processFileInclusion(importTag, InclusionKind.IMPORT);
}
+ public void visitProject(AntDomProject project) {
+ if (!myVisitedProjects.contains(project)) {
+ myVisitedProjects.add(project);
+ super.visitProject(project);
+ }
+ }
+
private void processFileInclusion(AntDomIncludingDirective directive, final InclusionKind kind) {
if (directive.equals(myContextElement)) {
stop();
package org.jetbrains.plugins.groovy.refactoring;
-import com.intellij.lang.refactoring.DefaultRefactoringSupportProvider;
+import com.intellij.lang.refactoring.RefactoringSupportProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope;
/**
* @author ilyas
*/
-public class GroovyRefactoringSupportProvider extends DefaultRefactoringSupportProvider {
+public class GroovyRefactoringSupportProvider extends RefactoringSupportProvider {
public static final GroovyRefactoringSupportProvider INSTANCE = new GroovyRefactoringSupportProvider();
}
@Override
- public boolean doInplaceRenameFor(PsiElement element, PsiElement context) {
+ public boolean isInplaceRenameAvailable(PsiElement element, PsiElement context) {
if (!(element instanceof GrVariable)) return false;
if (element instanceof GrField) return false;
*/
package com.intellij.lang.properties;
-import com.intellij.lang.refactoring.DefaultRefactoringSupportProvider;
+import com.intellij.lang.refactoring.RefactoringSupportProvider;
import com.intellij.psi.PsiElement;
-public class PropertiesRefactoringSupportProvider extends DefaultRefactoringSupportProvider {
+public class PropertiesRefactoringSupportProvider extends RefactoringSupportProvider {
public boolean isSafeDeleteAvailable(PsiElement element) {
return true;
}
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlFile;
+import com.intellij.psi.xml.XmlTag;
import com.intellij.util.IncorrectOperationException;
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
import org.intellij.plugins.relaxNG.compact.RncFileType;
return document;
}
+ @Override
+ public XmlTag getRootTag() {
+ return getDocument().getRootTag();
+ }
+
@Override
public boolean processDeclarations(@NotNull PsiScopeProcessor processor, @NotNull ResolveState substitutor, PsiElement lastParent, @NotNull PsiElement place) {
//processor.handleEvent(JavaScopeProcessorEvent.SET_CURRENT_FILE_CONTEXT, this);
@Override
public Pair<SvnChangeList, FilePath> getOneList(final VirtualFile file, VcsRevisionNumber number) throws VcsException {
- final VirtualFile root = ProjectLevelVcsManager.getInstance(myProject).getVcsRootFor(file);
+ final RootUrlInfo rootUrlInfo = myVcs.getSvnFileUrlMapping().getWcRootForFilePath(new File(file.getPath()));
+ final VirtualFile root = rootUrlInfo.getVirtualFile();
+ if (root == null) return null;
final SvnRepositoryLocation svnRootLocation = (SvnRepositoryLocation)getLocationFor(new FilePathImpl(root));
if (svnRootLocation == null) return null;
final String url = svnRootLocation.getURL();
import com.intellij.lang.cacheBuilder.SimpleWordsScanner;
import com.intellij.lang.cacheBuilder.WordsScanner;
import com.intellij.lang.findUsages.FindUsagesProvider;
-import com.intellij.lang.refactoring.DefaultRefactoringSupportProvider;
import com.intellij.lang.refactoring.NamesValidator;
import com.intellij.lang.refactoring.RefactoringSupportProvider;
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.SingleLazyInstanceSyntaxHighlighterFactory;
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
import com.intellij.openapi.project.Project;
}
}
- public static class XPathRefactoringSupportProvider extends DefaultRefactoringSupportProvider {
+ public static class XPathRefactoringSupportProvider extends RefactoringSupportProvider {
@Override
public boolean isSafeDeleteAvailable(PsiElement element) {
if (!element.isWritable() || element.getContainingFile() == null) return false;
}
@Override
- public boolean doInplaceRenameFor(PsiElement element, PsiElement context) {
+ public boolean isInplaceRenameAvailable(PsiElement element, PsiElement context) {
if (!element.isWritable() || element.getContainingFile() == null) return false;
final RefactoringSupportProvider realProvider = ContextProvider.getContextProvider(element).getRefactoringSupportProvider();
- return realProvider != null && realProvider.doInplaceRenameFor(element, context);
+ return realProvider != null && realProvider.isInplaceRenameAvailable(element, context);
}
@Override
import com.intellij.lang.cacheBuilder.WordsScanner;
import com.intellij.lang.findUsages.FindUsagesProvider;
import com.intellij.lang.findUsages.LanguageFindUsages;
-import com.intellij.lang.refactoring.DefaultRefactoringSupportProvider;
+import com.intellij.lang.refactoring.RefactoringSupportProvider;
import com.intellij.lang.xml.XMLLanguage;
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.NavigationItem;
XsltLanguage() {
super(ID);
LanguageFindUsages.INSTANCE.addExplicitExtension(this, new MyFindUsagesProvider());
- LanguageRefactoringSupport.INSTANCE.addExplicitExtension(this, new DefaultRefactoringSupportProvider() {
+ LanguageRefactoringSupport.INSTANCE.addExplicitExtension(this, new RefactoringSupportProvider() {
@Override
- public boolean doInplaceRenameFor(PsiElement element, PsiElement context) {
+ public boolean isInplaceRenameAvailable(PsiElement element, PsiElement context) {
return element instanceof XsltVariable && element.getUseScope() instanceof LocalSearchScope;
}
--- /dev/null
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.intellij.lang.xpath.xslt.refactoring;
+
+import com.intellij.lang.refactoring.RefactoringSupportProvider;
+import com.intellij.refactoring.RefactoringActionHandler;
+import org.intellij.lang.xpath.xslt.refactoring.introduceParameter.XsltIntroduceParameterAction;
+
+/**
+ * @author Dmitry Avdeev
+ */
+public class XsltRefactoringSupportProvider extends RefactoringSupportProvider {
+
+ @Override
+ public RefactoringActionHandler getIntroduceParameterHandler() {
+ return new XsltIntroduceParameterAction();
+ }
+}
package org.intellij.lang.xpath;
import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.testFramework.IdeaTestCase;
import com.intellij.testFramework.fixtures.CodeInsightTestFixture;
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
import com.intellij.testFramework.fixtures.JavaTestFixtureFactory;
* Date: 17.12.2008
*/
public abstract class TestBase extends TestCase {
- protected CodeInsightTestFixture myFixture;
+
+ protected TestBase() {
+ IdeaTestCase.initPlatformPrefix();
+ }
+
+ protected CodeInsightTestFixture myFixture;
@Override
protected void setUp() throws Exception {
<orderEntry type="module" module-name="xml" />
<orderEntry type="library" name="commons-collections" level="project" />
<orderEntry type="module" module-name="xslt-rt" />
- <orderEntry type="library" name="JUnit4" level="project" />
- <orderEntry type="module" module-name="testFramework-java" />
<orderEntry type="module" module-name="lvcs-impl" />
<orderEntry type="module" module-name="jam-support-impl" />
<orderEntry type="module" module-name="execution-openapi" />
<orderEntry type="module" module-name="annotations" />
<orderEntry type="library" name="Jaxen" level="project" />
+ <orderEntry type="module" module-name="resources-en" />
+ <orderEntry type="module" module-name="testFramework-java" scope="TEST" />
+ <orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
</component>
</module>
<separator/>
<action id="GenerateVisitorByHierarchy" internal="true" class="com.intellij.internal.GenerateVisitorByHierarchyAction" text="Generate Hierarchy Visitor"/>
<separator/>
- <action id="FocusDebugger" internal="true" class="com.intellij.internal.focus.FocusDebuggerAction" text="Start Focus Debugger"/>
- <action id="UiInspector" internal="true" class="com.intellij.internal.inspector.UiInspectorAction" text="UI Inspector"/>
- <separator/>
<action id="DumpLookupElementWeights" internal="true" class="com.intellij.internal.DumpLookupElementWeights" text="Dump lookup element weights"/>
<action id="CheckVfsSanity" internal="true" class="com.intellij.openapi.vfs.newvfs.persistent.CheckSanityAction" text="Check VFS sanity"/>
public boolean endsWithAttribute() {
return isAttributeBlock(getSubBlocks().get(getSubBlocks().size() - 1));
}
+
+ public Indent getChildIndent() {
+ return myChildIndent;
+ }
}
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlFile;
+import com.intellij.psi.xml.XmlTag;
import org.jetbrains.annotations.NotNull;
/**
return null;
}
+ @Override
+ public XmlTag getRootTag() {
+ XmlDocument document = getDocument();
+ return document == null ? null : document.getRootTag();
+ }
+
public boolean processElements(PsiElementProcessor processor, PsiElement place){
final XmlDocument document = getDocument();
return document == null || document.processElements(processor, place);
import com.intellij.psi.meta.MetaDataContributor;
import com.intellij.psi.meta.MetaDataRegistrar;
import com.intellij.psi.xml.*;
+import com.intellij.xml.impl.dtd.XmlNSDescriptorImpl;
import com.intellij.xml.impl.schema.NamedObjectDescriptor;
import com.intellij.xml.impl.schema.SchemaNSDescriptor;
import com.intellij.xml.impl.schema.XmlAttributeDescriptorImpl;
new ContentFilter(
new OrFilter(
new ClassFilter(XmlElementDecl.class),
+ new ClassFilter(XmlEntityDecl.class),
new ClassFilter(XmlConditionalSection.class),
new ClassFilter(XmlEntityRef.class)
)
),
new ClassFilter(XmlMarkupDecl.class)
),
- com.intellij.xml.impl.dtd.XmlNSDescriptorImpl.class
+ XmlNSDescriptorImpl.class
);
}
final PsiFile psiFile = result[0];
if (psiFile != null) {
- final String url = psiFile.getVirtualFile().getUrl();
- if (LOG.isDebugEnabled()) {
- LOG.debug("Adding external resource ref:"+systemId+","+url+","+super.toString());
+ final VirtualFile file = psiFile.getVirtualFile();
+ if (file != null) {
+ final String url = file.getUrl();
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Adding external resource ref:"+systemId+","+url+","+super.toString());
+ }
+ myExternalResourcesMap.put(systemId,url);
}
- myExternalResourcesMap.put(systemId,url);
}
return psiFile;
}
XMLInputSource source = new XMLInputSource(xmlResourceIdentifier);
if (xmlResourceIdentifier.getLiteralSystemId() == null) {
VirtualFile virtualFile = psiFile.getVirtualFile();
- final String url = VfsUtil.fixIDEAUrl(virtualFile.getUrl());
- source.setBaseSystemId(url);
- source.setSystemId(url);
+ if (virtualFile != null) {
+ final String url = VfsUtil.fixIDEAUrl(virtualFile.getUrl());
+ source.setBaseSystemId(url);
+ source.setSystemId(url);
+ }
}
source.setPublicId(publicId);
source.setCharacterStream(new StringReader(psiFile.getText()));
return null;
}
- @SuppressWarnings({"ConstantConditions"})
- public static XmlTag getRootTag(XmlFile file) {
- if (file == null) return null;
- final XmlDocument document = file.getDocument();
- if (document == null) return null;
- return document.getRootTag();
- }
-
@Nullable
public static String findNamespacePrefixByURI(XmlFile file, @NonNls String uri) {
- final XmlTag tag = getRootTag(file);
+ final XmlTag tag = file.getRootTag();
if (tag == null) return null;
for (XmlAttribute attribute : tag.getAttributes()) {
public interface XmlFile extends PsiFile, XmlElement, FileResolveScopeProvider {
@Nullable
XmlDocument getDocument();
+
+ @Nullable
+ XmlTag getRootTag();
}