Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Batkovich
2015-10-09 13:10:43 +03:00
53 changed files with 657 additions and 419 deletions
@@ -329,7 +329,9 @@ public class TargetOptionsComponent extends JPanel {
combo.setEditor(new BasicComboBoxEditor() {
@Override
protected JTextField createEditorComponent() {
return new HintTextField(COMPILER_DEFAULT, 12);
HintTextField editor = new HintTextField(COMPILER_DEFAULT, 12);
editor.setBorder(null);
return editor;
}
});
return combo;
@@ -185,6 +185,11 @@ public class DebugProcessEvents extends DebugProcessImpl {
}
getManagerThread().invokeAndWait(new DebuggerCommandImpl() {
@Override
public Priority getPriority() {
return Priority.HIGH;
}
@Override
protected void action() throws Exception {
if (eventSet.suspendPolicy() == EventRequest.SUSPEND_ALL) {
@@ -54,7 +54,9 @@ class JreComboboxEditor extends BasicComboBoxEditor {
@Override
protected JTextField createEditorComponent() {
return new JBTextField();
JBTextField field = new JBTextField();
field.setBorder(null);
return field;
}
public StatusText getEmptyText() {
@@ -239,13 +239,13 @@ public class JrePathEditor extends JPanel implements PanelWithAnchor {
@Override
public void render(SimpleColoredComponent component, boolean selected) {
component.append(getPresentableText());
component.append(FileUtil.toSystemDependentName(getPresentableText()));
component.setIcon(AllIcons.Nodes.Folder);
}
@Override
public String getPresentableText() {
return FileUtil.toSystemDependentName(myPath);
return myPath;
}
@Override
@@ -56,6 +56,11 @@ public class JavaParametersUtil {
Project project = configuration.getProject();
Module module = ProgramParametersUtil.getModule(configuration);
String alternativeJrePath = configuration.getAlternativeJrePath();
if (alternativeJrePath != null) {
configuration.setAlternativeJrePath(ProgramParametersUtil.expandPath(alternativeJrePath, null, project));
}
String vmParameters = configuration.getVMParameters();
if (vmParameters != null) {
vmParameters = ProgramParametersUtil.expandPath(vmParameters, module, project);
@@ -156,10 +161,7 @@ public class JavaParametersUtil {
return configuredJdk;
}
if (JdkUtil.checkForJdk(jreHome)) {
throw new CantRunException(ExecutionBundle.message("jre.path.is.jdk.error.message"));
}
if (!JdkUtil.checkForJre(jreHome)) {
if (!JdkUtil.checkForJre(jreHome) && !JdkUtil.checkForJdk(jreHome)) {
throw new CantRunException(ExecutionBundle.message("jre.path.is.not.valid.jre.home.error.message", jreHome));
}
@@ -640,7 +640,7 @@ public class ExtractMethodProcessor implements MatchProvider {
if (classCopy == null) {
return null;
}
final PsiMethod emptyMethod = (PsiMethod)classCopy.addAfter(generateEmptyMethod("name"), PsiTreeUtil.getParentOfType(classCopy, PsiMember.class));
final PsiMethod emptyMethod = (PsiMethod)classCopy.addAfter(generateEmptyMethod("name"), classCopy.getLBrace());
prepareMethodBody(emptyMethod, false);
if (myNotNullConditionalCheck || myNullConditionalCheck) {
return Nullness.NULLABLE;
@@ -671,6 +671,7 @@ public class ExtractMethodProcessor implements MatchProvider {
}
final String nameByComment = getNameByComment();
final PsiField field = JavaPsiFacade.getElementFactory(myProject).createField("fieldNameToReplace", myReturnType instanceof PsiEllipsisType ? ((PsiEllipsisType)myReturnType).toArrayType() : myReturnType);
final List<String> getters = new ArrayList<String>(ContainerUtil.map(initialMethodNames, new Function<String, String>() {
@Override
public String fun(String propertyName) {
@@ -678,7 +679,8 @@ public class ExtractMethodProcessor implements MatchProvider {
LOG.info(propertyName + "; " + myExpression);
return null;
}
return GenerateMembersUtil.suggestGetterName(propertyName, myReturnType, myProject);
field.setName(propertyName);
return GenerateMembersUtil.suggestGetterName(field);
}
}));
ContainerUtil.addIfNotNull(nameByComment, getters);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -82,7 +82,7 @@ public class JavaTestFinder implements TestFinder {
}
}
private static boolean isTestSubjectClass(PsiClass klass) {
protected boolean isTestSubjectClass(PsiClass klass) {
if (klass.isAnnotationType() ||
TestFrameworks.getInstance().isTestClass(klass) ||
!klass.isPhysical()) {
@@ -114,11 +114,10 @@ public class JavaTestFinder implements TestFinder {
HashSet<String> names = new HashSet<String>();
cache.getAllClassNames(names);
final TestFrameworks frameworks = TestFrameworks.getInstance();
for (String eachName : names) {
if (pattern.matcher(eachName).matches()) {
for (PsiClass eachClass : cache.getClassesByName(eachName, scope)) {
if (eachClass.isPhysical() && (frameworks.isTestClass(eachClass) || frameworks.isPotentialTestClass(eachClass))) {
if (isTestClass(eachClass)) {
if (!processor.process(Pair.create(eachClass, TestFinderHelper.calcTestNameProximity(klassName, eachName)))) {
return true;
}
@@ -129,6 +128,11 @@ public class JavaTestFinder implements TestFinder {
return false;
}
protected boolean isTestClass(PsiClass eachClass) {
final TestFrameworks frameworks = TestFrameworks.getInstance();
return eachClass.isPhysical() && (frameworks.isTestClass(eachClass) || frameworks.isPotentialTestClass(eachClass));
}
@Nullable
private static Module getModule(PsiElement element) {
ProjectFileIndex index = ProjectRootManager.getInstance(element.getProject()).getFileIndex();
@@ -83,7 +83,7 @@ public class CreateTestDialog extends DialogWrapper {
private final PsiPackage myTargetPackage;
private final Module myTargetModule;
private PsiDirectory myTargetDirectory;
protected PsiDirectory myTargetDirectory;
private TestFramework mySelectedFramework;
private final ComboBox myLibrariesCombo = new ComboBox(new DefaultComboBoxModel());
@@ -466,16 +466,24 @@ public class CreateTestDialog extends DialogWrapper {
RecentsManager.getInstance(myProject).registerRecentEntry(RECENTS_KEY, myTargetPackageField.getText());
RecentsManager.getInstance(myProject).registerRecentEntry(RECENT_SUPERS_KEY, mySuperClassField.getText());
String errorMessage;
String errorMessage = null;
try {
myTargetDirectory = selectTargetDirectory();
if (myTargetDirectory == null) return;
errorMessage = RefactoringMessageUtil.checkCanCreateClass(myTargetDirectory, getClassName());
}
catch (IncorrectOperationException e) {
errorMessage = e.getMessage();
}
if (errorMessage == null) {
try {
errorMessage = checkCanCreateClass();
}
catch (IncorrectOperationException e) {
errorMessage = e.getMessage();
}
}
if (errorMessage != null) {
final int result = Messages
.showOkCancelDialog(myProject, errorMessage + ". Update existing class?", CommonBundle.getErrorTitle(), Messages.getErrorIcon());
@@ -490,6 +498,10 @@ public class CreateTestDialog extends DialogWrapper {
super.doOKAction();
}
protected String checkCanCreateClass() {
return RefactoringMessageUtil.checkCanCreateClass(myTargetDirectory, getClassName());
}
@Nullable
private PsiDirectory selectTargetDirectory() throws IncorrectOperationException {
final String packageName = getPackageName();
@@ -135,7 +135,7 @@ public class AppMain {
System.err.println("main method should be static");
return;
}
if (!Void.class.isInstance(m.getReturnType())) {
if (!void.class.isAssignableFrom(m.getReturnType())) {
System.err.println("main method must return a value of type void");
return;
}
@@ -415,6 +415,10 @@ abstract class ComponentStoreImpl : IComponentStore {
}
}
@TestOnly fun removeComponent(name: String) {
components.remove(name)
}
companion object {
protected fun executeSave(session: SaveSession, readonlyFiles: MutableList<JBPair<SaveSession, VirtualFile>>, previousErrors: MutableList<Throwable>?): MutableList<Throwable>? {
var errors = previousErrors
@@ -62,11 +62,12 @@ open class DirectoryBasedStorage(private val dir: File,
override fun getSerializedState(storageData: StateMap, component: Any?, componentName: String, archive: Boolean): Element? {
this.componentName = componentName
val state = Element(FileStorageCoreUtil.COMPONENT)
if (storageData.isEmpty()) {
return state
return null
}
val state = Element(FileStorageCoreUtil.COMPONENT)
if (splitter is StateSplitterEx) {
for (fileName in storageData.keys()) {
val subState = storageData.getState(fileName, archive) ?: return null
@@ -4,12 +4,14 @@ import com.intellij.externalDependencies.DependencyOnPlugin
import com.intellij.externalDependencies.ExternalDependenciesManager
import com.intellij.externalDependencies.ProjectExternalDependency
import com.intellij.openapi.application.ex.ApplicationManagerEx
import com.intellij.openapi.components.StoragePathMacros
import com.intellij.openapi.components.service
import com.intellij.openapi.components.stateStore
import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.components.*
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.util.JDOMUtil
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.testFramework.*
import org.assertj.core.api.Assertions.assertThat
import org.jdom.Element
import org.junit.ClassRule
import org.junit.Rule
import org.junit.Test
@@ -18,6 +20,22 @@ import java.nio.file.Paths
internal class DefaultProjectStoreTest {
companion object {
@ClassRule val projectRule = ProjectRule()
private const val TEST_COMPONENT_NAME = "Foo"
@State(name = TEST_COMPONENT_NAME, storages = arrayOf(
Storage(file = StoragePathMacros.PROJECT_FILE),
Storage(file = "${StoragePathMacros.PROJECT_CONFIG_DIR}/testSchemes", scheme = StorageScheme.DIRECTORY_BASED, stateSplitter = TestStateSplitter::class))
)
private class TestComponent: PersistentStateComponent<Element> {
private var element = Element("state")
override fun getState() = element.clone()
override fun loadState(state: Element) {
element = state.clone()
}
}
}
private val tempDirManager = TemporaryDirectory()
@@ -28,6 +46,10 @@ internal class DefaultProjectStoreTest {
tempDirManager,
WrapRule {
val app = ApplicationManagerEx.getApplicationEx()
val path = Paths.get(app.stateStore.stateStorageManager.expandMacros(StoragePathMacros.APP_CONFIG))
// dream about using in memory fs per test as ICS partially does and avoid such hacks
path.refreshVfs()
val isDoNotSave = app.isDoNotSave
app.doNotSave(false);
{
@@ -35,24 +57,45 @@ internal class DefaultProjectStoreTest {
app.doNotSave(isDoNotSave)
}
finally {
Paths.get(app.stateStore.stateStorageManager.expandMacros(StoragePathMacros.APP_CONFIG)).deleteRecursively()
path.deleteRecursively()
val virtualFile = LocalFileSystem.getInstance().findFileByPathIfCached(path.systemIndependentPath)
runInEdtAndWait { runWriteAction { virtualFile?.delete(null) } }
}
}
},
WrapRule {
val externalDependenciesManager = ProjectManager.getInstance().defaultProject.service<ExternalDependenciesManager>()
externalDependenciesManager.allDependencies = requiredPlugins
{
externalDependenciesManager.allDependencies = emptyList()
}
}
)
@Rule fun getChain() = ruleChain
@Test fun `new project from default`() {
createProjectAndUseInLoadComponentStateMode(tempDirManager) {
assertThat(it.service<ExternalDependenciesManager>().allDependencies).isEqualTo(requiredPlugins)
@Test fun `new project from default - file-based storage`() {
val externalDependenciesManager = ProjectManager.getInstance().defaultProject.service<ExternalDependenciesManager>()
externalDependenciesManager.allDependencies = requiredPlugins
try {
createProjectAndUseInLoadComponentStateMode(tempDirManager) {
assertThat(it.service<ExternalDependenciesManager>().allDependencies).isEqualTo(requiredPlugins)
}
}
finally {
externalDependenciesManager.allDependencies = emptyList()
}
}
@Test fun `new project from default - directory-based storage`() {
val defaultProject = ProjectManager.getInstance().defaultProject
val defaultTestComponent = TestComponent()
defaultTestComponent.loadState(JDOMUtil.load("""<component><main name="$TEST_COMPONENT_NAME"/><sub name="foo" /><sub name="bar" /></component>""".reader()))
val stateStore = defaultProject.stateStore as ComponentStoreImpl
stateStore.initComponent(defaultTestComponent, true)
try {
// obviously, project must be directory-based also
createProjectAndUseInLoadComponentStateMode(tempDirManager, directoryBased = true) {
val component = TestComponent()
it.stateStore.initComponent(component, true)
assertThat(JDOMUtil.writeElement(component.state)).isEqualTo(JDOMUtil.writeElement(defaultTestComponent.state))
}
}
finally {
stateStore.removeComponent(TEST_COMPONENT_NAME)
}
}
}
@@ -44,8 +44,16 @@ private fun StateStorageBase<*>.setStateAndSave(componentName: String, state: St
externalizationSession.save()
}
internal class TestStateSplitter : MainConfigurationStateSplitter() {
override fun getComponentStateFileName() = "main"
override fun getSubStateTagName() = "sub"
override fun getSubStateFileName(element: Element) = element.getAttributeValue("name")
}
@Bombed(year = 2015, month = Calendar.OCTOBER, day = 10)
class DirectoryBasedStorageTest {
internal class DirectoryBasedStorageTest {
companion object {
@ClassRule val projectRule = ProjectRule()
}
@@ -57,13 +65,7 @@ class DirectoryBasedStorageTest {
@Test fun save() {
val dir = tempDirManager.newPath()
val storage = DirectoryBasedStorage(dir.toFile(), object : MainConfigurationStateSplitter() {
override fun getComponentStateFileName() = "main"
override fun getSubStateTagName() = "sub"
override fun getSubStateFileName(element: Element) = element.getAttributeValue("name")
})
val storage = DirectoryBasedStorage(dir.toFile(), TestStateSplitter())
val componentName = "test"
@@ -33,19 +33,19 @@ import org.junit.Rule
import org.junit.Test
import java.io.File
fun createProjectAndUseInLoadComponentStateMode(tempDirManager: TemporaryDirectory, task: (Project) -> Unit) {
createOrLoadProject(tempDirManager, task)
fun createProjectAndUseInLoadComponentStateMode(tempDirManager: TemporaryDirectory, directoryBased: Boolean = false, task: (Project) -> Unit) {
createOrLoadProject(tempDirManager, task, directoryBased = directoryBased)
}
fun loadAndUseProject(tempDirManager: TemporaryDirectory, projectCreator: ((VirtualFile) -> String)? = null, task: (Project) -> Unit) {
createOrLoadProject(tempDirManager, task, projectCreator)
fun loadAndUseProject(tempDirManager: TemporaryDirectory, projectCreator: ((VirtualFile) -> String), task: (Project) -> Unit) {
createOrLoadProject(tempDirManager, task, projectCreator, false)
}
private fun createOrLoadProject(tempDirManager: TemporaryDirectory, task: (Project) -> Unit, projectCreator: ((VirtualFile) -> String)? = null) {
private fun createOrLoadProject(tempDirManager: TemporaryDirectory, task: (Project) -> Unit, projectCreator: ((VirtualFile) -> String)? = null, directoryBased: Boolean) {
runInEdtAndWait {
var filePath: String
if (projectCreator == null) {
filePath = tempDirManager.newDirectory("test${ProjectFileType.DOT_DEFAULT_EXTENSION}").systemIndependentPath
filePath = tempDirManager.newDirectory("test${if (directoryBased) "" else ProjectFileType.DOT_DEFAULT_EXTENSION}").systemIndependentPath
}
else {
filePath = runWriteAction { projectCreator(tempDirManager.newVirtualDirectory()) }
@@ -614,16 +614,9 @@ public class SingleRootFileViewProvider extends UserDataHolderBase implements Fi
@Override
public long getModificationStamp() {
final VirtualFile virtualFile = getVirtualFile();
if (virtualFile instanceof LightVirtualFile) {
Document doc = getCachedDocument();
if (doc != null) return getLastCommittedStamp(doc);
return virtualFile.getModificationStamp();
}
final Document document = getDocument();
final Document document = getCachedDocument();
if (document == null) {
return virtualFile.getModificationStamp();
return getVirtualFile().getModificationStamp();
}
return getLastCommittedStamp(document);
}
@@ -321,7 +321,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document);
if (virtualFile != null) {
((SmartPointerManagerImpl)SmartPointerManager.getInstance(myProject)).fastenBelts(virtualFile);
getSmartPointerManager().fastenBelts(virtualFile);
}
myIsCommitInProgress = true;
@@ -340,6 +340,9 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
}
if (success) {
clearUncommittedInfo(document);
if (virtualFile != null) {
getSmartPointerManager().updatePointerTargetsAfterReparse(virtualFile);
}
viewProvider.contentsSynchronized();
}
}
@@ -792,12 +795,16 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
private UncommittedInfo clearUncommittedInfo(@NotNull Document document) {
UncommittedInfo info = myUncommittedInfos.remove(document);
if (info != null) {
((SmartPointerManagerImpl)SmartPointerManager.getInstance(myProject)).updatePointers(document, info.myFrozen, info.myEvents);
getSmartPointerManager().updatePointers(document, info.myFrozen, info.myEvents);
info.removeListener();
}
return info;
}
private SmartPointerManagerImpl getSmartPointerManager() {
return (SmartPointerManagerImpl)SmartPointerManager.getInstance(myProject);
}
private boolean isRelevant(@NotNull VirtualFile virtualFile) {
return !virtualFile.getFileType().isBinary() && !myProject.isDisposed();
}
@@ -130,6 +130,7 @@ class AnchorElementInfo extends SelfElementInfo {
if (anchor == null) anchor = element;
myType = anchor.getClass();
setRange(anchor.getTextRange());
myMarkerCache.rangeChanged(markerCacheKey());
myStubElementTypeAndId = pack(-1, null);
}
}
@@ -23,7 +23,6 @@ import com.intellij.openapi.editor.impl.event.RetargetRangeMarkers;
import com.intellij.openapi.util.ProperTextRange;
import com.intellij.openapi.util.Trinity;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.TLongObjectHashMap;
@@ -112,40 +111,17 @@ class MarkerCache {
synchronized void updateMarkers(@NotNull FrozenDocument frozen, @NotNull List<DocumentEvent> events) {
TLongObjectHashMap<ManualRangeMarker> updated = getUpdatedMarkers(frozen, events);
for (SmartPsiElementPointerImpl pointer : myPointers.getAlivePointers()) {
SmartPointerElementInfo info = pointer.getElementInfo();
if (info instanceof SelfElementInfo) {
long key = ((SelfElementInfo)info).markerCacheKey();
if (key != 0) {
ManualRangeMarker newRangeMarker = updated.get(key);
ProperTextRange newRange = newRangeMarker == null ? null : newRangeMarker.getRange();
((SelfElementInfo)info).setRange(newRange);
if (newRange != null && !(pointer instanceof SmartPsiFileRangePointerImpl)) {
updatePointerTarget(pointer, newRange);
}
}
for (SelfElementInfo info : getInfos()) {
long key = info.markerCacheKey();
if (key != 0) {
ManualRangeMarker newRangeMarker = updated.get(key);
info.setRange(newRangeMarker == null ? null : newRangeMarker.getRange());
}
}
myUpdatedRanges = null;
}
// after reparse and its complex tree diff, the element might have "moved" to other range
// but if an element of the same type can still be found at the old range, let's point there
private static <E extends PsiElement> void updatePointerTarget(@NotNull SmartPsiElementPointerImpl<E> pointer, @NotNull ProperTextRange newRange) {
E cachedElement = pointer.getCachedElement();
if (cachedElement == null || cachedElement.isValid() && newRange.equals(cachedElement.getTextRange())) {
return;
}
E newTarget = pointer.doRestoreElement();
if (newTarget != null) {
pointer.cacheElement(newTarget);
}
}
@NotNull
private List<SelfElementInfo> getInfos() {
return ContainerUtil.findAll(ContainerUtil.map(myPointers.getAlivePointers(), new NullableFunction<SmartPsiElementPointerImpl, SmartPointerElementInfo>() {
@@ -40,7 +40,7 @@ public class SelfElementInfo extends SmartPointerElementInfo {
protected volatile Class myType;
private final SmartPointerManagerImpl myManager;
protected final Language myLanguage;
private final MarkerCache myMarkerCache;
protected final MarkerCache myMarkerCache;
private final boolean myForInjected;
private boolean myHasRange;
private int myStartOffset;
@@ -60,6 +60,7 @@ public class SelfElementInfo extends SmartPointerElementInfo {
myManager = (SmartPointerManagerImpl)SmartPointerManager.getInstance(project);
myMarkerCache = myManager.getMarkerCache(containingFile.getViewProvider().getVirtualFile());
setRange(range);
myMarkerCache.rangeChanged(markerCacheKey());
}
void setRange(@Nullable Segment range) {
@@ -67,7 +68,6 @@ public class SelfElementInfo extends SmartPointerElementInfo {
myHasRange = true;
myStartOffset = range.getStartOffset();
myEndOffset = range.getEndOffset();
myMarkerCache.rangeChanged(markerCacheKey());
} else {
myHasRange = false;
}
@@ -23,10 +23,7 @@ import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.impl.FrozenDocument;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.LowMemoryWatcher;
import com.intellij.openapi.util.ProperTextRange;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiDocumentManagerBase;
@@ -245,6 +242,32 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
list.markerCache.updateMarkers(frozen, events);
}
public void updatePointerTargetsAfterReparse(@NotNull VirtualFile file) {
FilePointersList list = getPointers(file);
if (list == null) return;
for (SmartPsiElementPointerImpl pointer : list.getAlivePointers()) {
if (!(pointer instanceof SmartPsiFileRangePointerImpl) && pointer.getElementInfo() instanceof SelfElementInfo) {
updatePointerTarget(pointer, pointer.getPsiRange());
}
}
}
// after reparse and its complex tree diff, the element might have "moved" to other range
// but if an element of the same type can still be found at the old range, let's point there
private static <E extends PsiElement> void updatePointerTarget(@NotNull SmartPsiElementPointerImpl<E> pointer, @Nullable Segment pointerRange) {
E cachedElement = pointer.getCachedElement();
if (cachedElement == null || cachedElement.isValid() && pointerRange != null && pointerRange.equals(cachedElement.getTextRange())) {
return;
}
E newTarget = pointer.doRestoreElement();
if (newTarget != null) {
pointer.cacheElement(newTarget);
}
}
Project getProject() {
return myProject;
}
@@ -308,6 +308,7 @@ public final class Presentation implements Cloneable {
setDescription(presentation.getDescription());
setIcon(presentation.getIcon());
setDisabledIcon(presentation.getDisabledIcon());
setHoveredIcon(presentation.getHoveredIcon());
setVisible(presentation.isVisible());
setEnabled(presentation.isEnabled());
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -129,6 +129,7 @@ public class SelectWordHandler extends EditorActionHandler {
}
}
if (element instanceof PsiFile) return null;
element = element.getNextSibling();
if (element == null) return null;
TextRange range = element.getTextRange();
@@ -18,18 +18,48 @@ package com.intellij.execution.impl;
import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.openapi.options.ex.SingleConfigurableEditor;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
public class EditConfigurationsDialog extends SingleConfigurableEditor implements RunConfigurable.RunDialogBase {
protected Executor myExecutor;
public EditConfigurationsDialog(final Project project) {
super(project, new RunConfigurable(project), "#com.intellij.execution.impl.EditConfigurationsDialog", IdeModalityType.PROJECT);
this(project, null);
}
public EditConfigurationsDialog(final Project project, @Nullable final ConfigurationFactory factory) {
super(project, new RunConfigurable(project).selectConfigurableOnShow(factory == null), "#com.intellij.execution.impl.EditConfigurationsDialog", IdeModalityType.PROJECT);
((RunConfigurable)getConfigurable()).setRunDialog(this);
setTitle(ExecutionBundle.message("run.debug.dialog.title"));
setHorizontalStretch(1.3F);
if (factory != null) {
addRunConfiguration(factory);
}
}
public void addRunConfiguration(@NotNull final ConfigurationFactory factory) {
final RunConfigurable configurable = (RunConfigurable)getConfigurable();
final SingleConfigurationConfigurable<RunConfiguration> configuration = configurable.createNewConfiguration(factory);
if (!isVisible()) {
getContentPanel().addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
if (configuration != null) {
configurable.updateRightPanel(configuration);
getContentPanel().removeComponentListener(this);
}
}
});
}
}
@Override
@@ -0,0 +1,128 @@
/*
* Copyright 2000-2015 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.execution.impl;
import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.ListPopup;
import com.intellij.openapi.ui.popup.ListPopupStep;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.util.Consumer;
import com.intellij.util.ui.EmptyIcon;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
/**
* @author Irina.Chernushina on 10/8/2015.
*/
public class NewRunConfigurationPopup {
@NotNull
public static ListPopup createAddPopup(@NotNull final List<ConfigurationType> typesToShow,
@NotNull final String defaultText,
@NotNull final Consumer<ConfigurationFactory> creator,
@Nullable final ConfigurationType selectedConfigurationType,
@NotNull final Runnable finalStep, boolean showTitle) {
return JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep<ConfigurationType>(
showTitle ? ExecutionBundle.message("add.new.run.configuration.acrtion.name") : null, typesToShow) {
@Override
@NotNull
public String getTextFor(final ConfigurationType type) {
return type != null ? type.getDisplayName() : defaultText;
}
@Override
public boolean isSpeedSearchEnabled() {
return true;
}
@Override
public boolean canBeHidden(ConfigurationType value) {
return true;
}
@Override
public Icon getIconFor(final ConfigurationType type) {
return type != null ? type.getIcon() : EmptyIcon.ICON_16;
}
@Override
public PopupStep onChosen(final ConfigurationType type, final boolean finalChoice) {
if (hasSubstep(type)) {
return getSupStep(type);
}
if (type == null) {
return doFinalStep(finalStep);
}
final ConfigurationFactory[] factories = type.getConfigurationFactories();
if (factories.length > 0) {
creator.consume(factories[0]);
}
return FINAL_CHOICE;
}
@Override
public int getDefaultOptionIndex() {
return selectedConfigurationType != null ? typesToShow.indexOf(selectedConfigurationType) : super.getDefaultOptionIndex();
}
private ListPopupStep getSupStep(final ConfigurationType type) {
final ConfigurationFactory[] factories = type.getConfigurationFactories();
Arrays.sort(factories, new Comparator<ConfigurationFactory>() {
@Override
public int compare(final ConfigurationFactory factory1, final ConfigurationFactory factory2) {
return factory1.getName().compareToIgnoreCase(factory2.getName());
}
});
return new BaseListPopupStep<ConfigurationFactory>(
ExecutionBundle.message("add.new.run.configuration.action.name", type.getDisplayName()), factories) {
@Override
@NotNull
public String getTextFor(final ConfigurationFactory value) {
return value.getName();
}
@Override
public Icon getIconFor(final ConfigurationFactory factory) {
return factory.getIcon();
}
@Override
public PopupStep onChosen(final ConfigurationFactory factory, final boolean finalChoice) {
creator.consume(factory);
return FINAL_CHOICE;
}
};
}
@Override
public boolean hasSubstep(final ConfigurationType type) {
return type != null && type.getConfigurationFactories().length > 1;
}
});
}
}
@@ -28,11 +28,7 @@ import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.options.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.ListPopup;
import com.intellij.openapi.ui.popup.ListPopupStep;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Trinity;
@@ -42,6 +38,7 @@ import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.labels.ActionLink;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.Consumer;
import com.intellij.util.IconUtil;
import com.intellij.util.PlatformIcons;
import com.intellij.util.containers.ContainerUtil;
@@ -295,13 +292,19 @@ class RunConfigurable extends BaseConfigurable {
clickDefaultButton();
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), JComponent.WHEN_FOCUSED);
sortTopLevelBranches();
((DefaultTreeModel)myTree.getModel()).reload();
}
protected RunConfigurable selectConfigurableOnShow(final boolean option) {
if (!option) return this;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (isDisposed) return;
myTree.requestFocusInWindow();
final RunnerAndConfigurationSettings settings = manager.getSelectedConfiguration();
final RunnerAndConfigurationSettings settings = getRunManager().getSelectedConfiguration();
if (settings != null) {
if (selectConfiguration(settings.getConfiguration())) {
return;
@@ -314,8 +317,7 @@ class RunConfigurable extends BaseConfigurable {
drawPressAddButtonMessage(null);
}
});
sortTopLevelBranches();
((DefaultTreeModel)myTree.getModel()).reload();
return this;
}
private boolean selectConfiguration(@NotNull RunConfiguration configuration) {
@@ -392,7 +394,7 @@ class RunConfigurable extends BaseConfigurable {
myRunDialog = runDialog;
}
private void updateRightPanel(final Configurable configurable) {
void updateRightPanel(final Configurable configurable) {
myRightPanel.removeAll();
mySelectedConfigurable = configurable;
@@ -1093,7 +1095,7 @@ class RunConfigurable extends BaseConfigurable {
return configurationConfigurable;
}
private void createNewConfiguration(final ConfigurationFactory factory) {
SingleConfigurationConfigurable<RunConfiguration> createNewConfiguration(final ConfigurationFactory factory) {
DefaultMutableTreeNode node = null;
DefaultMutableTreeNode selectedNode = null;
TreePath selectionPath = myTree.getSelectionPath();
@@ -1118,7 +1120,7 @@ class RunConfigurable extends BaseConfigurable {
if (factory instanceof ConfigurationFactoryEx) {
((ConfigurationFactoryEx)factory).onNewConfigurationCreated(settings.getConfiguration());
}
createNewConfiguration(settings, node, selectedNode);
return createNewConfiguration(settings, node, selectedNode);
}
private class MyToolbarAddAction extends AnAction implements AnActionButtonRunnable {
@@ -1152,92 +1154,18 @@ class RunConfigurable extends BaseConfigurable {
configurationTypes.add(null);
}
final ListPopup popup = JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep<ConfigurationType>(
ExecutionBundle.message("add.new.run.configuration.acrtion.name"), configurationTypes) {
final ListPopup popup = NewRunConfigurationPopup.createAddPopup(configurationTypes, hiddenCount + " items more (irrelevant)...",
new Consumer<ConfigurationFactory>() {
@Override
public void consume(ConfigurationFactory factory) {
createNewConfiguration(factory);
}
}, getSelectedConfigurationType(), new Runnable() {
@Override
@NotNull
public String getTextFor(final ConfigurationType type) {
return type != null ? type.getDisplayName() : hiddenCount + " items more (irrelevant)...";
public void run() {
showAddPopup(false);
}
@Override
public boolean isSpeedSearchEnabled() {
return true;
}
@Override
public boolean canBeHidden(ConfigurationType value) {
return true;
}
@Override
public Icon getIconFor(final ConfigurationType type) {
return type != null ? type.getIcon() : EmptyIcon.ICON_16;
}
@Override
public PopupStep onChosen(final ConfigurationType type, final boolean finalChoice) {
if (hasSubstep(type)) {
return getSupStep(type);
}
if (type == null) {
return doFinalStep(new Runnable() {
@Override
public void run() {
showAddPopup(false);
}
});
}
final ConfigurationFactory[] factories = type.getConfigurationFactories();
if (factories.length > 0) {
createNewConfiguration(factories[0]);
}
return FINAL_CHOICE;
}
@Override
public int getDefaultOptionIndex() {
ConfigurationType type = getSelectedConfigurationType();
return type != null ? configurationTypes.indexOf(type) : super.getDefaultOptionIndex();
}
private ListPopupStep getSupStep(final ConfigurationType type) {
final ConfigurationFactory[] factories = type.getConfigurationFactories();
Arrays.sort(factories, new Comparator<ConfigurationFactory>() {
@Override
public int compare(final ConfigurationFactory factory1, final ConfigurationFactory factory2) {
return factory1.getName().compareToIgnoreCase(factory2.getName());
}
});
return new BaseListPopupStep<ConfigurationFactory>(
ExecutionBundle.message("add.new.run.configuration.action.name", type.getDisplayName()), factories) {
@Override
@NotNull
public String getTextFor(final ConfigurationFactory value) {
return value.getName();
}
@Override
public Icon getIconFor(final ConfigurationFactory factory) {
return factory.getIcon();
}
@Override
public PopupStep onChosen(final ConfigurationFactory factory, final boolean finalChoice) {
createNewConfiguration(factory);
return FINAL_CHOICE;
}
};
}
@Override
public boolean hasSubstep(final ConfigurationType type) {
return type != null && type.getConfigurationFactories().length > 1;
}
});
}, true);
//new TreeSpeedSearch(myTree);
popup.showUnderneathOf(myToolbarDecorator.getActionsPanel());
}
@@ -1267,7 +1195,6 @@ class RunConfigurable extends BaseConfigurable {
}
}
private class MyRemoveAction extends AnAction implements AnActionButtonRunnable, AnActionButtonUpdater{
public MyRemoveAction() {
@@ -15,14 +15,14 @@
*/
package com.intellij.execution.startup;
import com.intellij.execution.Executor;
import com.intellij.execution.RunManager;
import com.intellij.execution.RunManagerEx;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.*;
import com.intellij.execution.actions.ChooseRunConfigurationPopup;
import com.intellij.execution.actions.ExecutorProvider;
import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.execution.impl.EditConfigurationsDialog;
import com.intellij.execution.impl.NewRunConfigurationPopup;
import com.intellij.execution.impl.RunManagerImpl;
import com.intellij.icons.AllIcons;
import com.intellij.idea.ActionsBundle;
@@ -30,19 +30,24 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.ListPopup;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.ui.*;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.JBCheckBox;
import com.intellij.ui.components.JBList;
import com.intellij.ui.popup.PopupFactoryImpl;
import com.intellij.ui.table.JBTable;
import com.intellij.util.Consumer;
import com.intellij.util.IconUtil;
import com.intellij.util.ui.FormBuilder;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nls;
@@ -189,6 +194,57 @@ public class ProjectStartupConfigurable implements SearchableConfigurable, Confi
myTable.getSelectionModel().setLeadSelectionIndex(0);
}
private ChooseRunConfigurationPopup.ItemWrapper<Void> createNewWrapper(final AnActionButton button) {
return new ChooseRunConfigurationPopup.ItemWrapper<Void>(null) {
@Override
public Icon getIcon() {
return IconUtil.getAddIcon();
}
@Override
public String getText() {
return UIUtil.removeMnemonic(ExecutionBundle.message("add.new.run.configuration.acrtion.name"));
}
@Override
public void perform(@NotNull final Project project, @NotNull final Executor executor, @NotNull DataContext context) {
final RunManagerEx runManager = RunManagerImpl.getInstanceEx(project);
final ConfigurationType[] factories = runManager.getConfigurationFactories();
// todo filter list
final List<ConfigurationType> factoriesList = Arrays.asList(factories);
final ListPopup popup = NewRunConfigurationPopup.createAddPopup(factoriesList, "", new Consumer<ConfigurationFactory>() {
@Override
public void consume(final ConfigurationFactory factory) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
final EditConfigurationsDialog dialog = new EditConfigurationsDialog(project, factory);
if (dialog.showAndGet()) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
RunnerAndConfigurationSettings configuration = RunManager.getInstance(project).getSelectedConfiguration();
if (configuration != null) {
myModel.addConfiguration(configuration);
selectPathOrFirst(configuration);
}
}
}, ModalityState.any(), project.getDisposed());
}
}
}, ModalityState.any(), project.getDisposed());
}
}, null, EmptyRunnable.getInstance(), false);
showPopup(button, popup);
}
@Override
public boolean available(Executor executor) {
return true;
}
};
}
private ChooseRunConfigurationPopup.ItemWrapper<Void> createEditWrapper() {
return new ChooseRunConfigurationPopup.ItemWrapper<Void>(null) {
@Override
@@ -227,7 +283,8 @@ public class ProjectStartupConfigurable implements SearchableConfigurable, Confi
private void selectAndAddConfiguration(final AnActionButton button) {
final Executor executor = DefaultRunExecutor.getRunExecutorInstance();
final List<ChooseRunConfigurationPopup.ItemWrapper> wrappers = new ArrayList<ChooseRunConfigurationPopup.ItemWrapper>();
wrappers.add(createEditWrapper());
wrappers.add(createNewWrapper(button));
//wrappers.add(createEditWrapper());
final ChooseRunConfigurationPopup.ItemWrapper[] allSettings =
ChooseRunConfigurationPopup.createSettingsList(myProject, new ExecutorProvider() {
@Override
@@ -272,6 +329,10 @@ public class ProjectStartupConfigurable implements SearchableConfigurable, Confi
})
.createPopup();
showPopup(button, popup);
}
private void showPopup(AnActionButton button, JBPopup popup) {
final RelativePoint point = button.getPreferredPopupPoint();
if (point != null) {
popup.show(point);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -19,6 +19,7 @@ import com.intellij.openapi.editor.richcopy.model.ColorRegistry;
import com.intellij.openapi.editor.richcopy.model.FontNameRegistry;
import com.intellij.openapi.editor.richcopy.model.MarkupHandler;
import com.intellij.openapi.editor.richcopy.model.SyntaxInfo;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.util.ui.UIUtil;
import gnu.trove.TIntObjectHashMap;
import org.jetbrains.annotations.NotNull;
@@ -83,7 +84,11 @@ public class HtmlTransferableData extends AbstractSyntaxAwareReaderTransferableD
else {
myFontFamily = myDefaultFontFamily = -1;
}
myResultBuffer.append(String.format("font-size:%.1fpt;\">", mySyntaxInfo.getFontSize()));
float fontSize = mySyntaxInfo.getFontSize();
// on Mac OS font size in points declared in HTML doesn't mean the same value as when declared e.g. in TextEdit (and in Java),
// this is the correction factor
if (SystemInfo.isMac) fontSize *= 0.75f;
myResultBuffer.append(String.format("font-size:%.1fpt;\">", fontSize));
mySyntaxInfo.processOutputInfo(this);
@@ -57,10 +57,15 @@ public class DependenciesToolWindow {
});
}
public void addContent(Content content) {
myContentManager.addContent(content);
myContentManager.setSelectedContent(content);
ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.DEPENDENCIES).activate(null);
public void addContent(final Content content) {
final Runnable runnable = new Runnable() {
public void run() {
myContentManager.addContent(content);
myContentManager.setSelectedContent(content);
ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.DEPENDENCIES).activate(null);
}
};
StartupManager.getInstance(myProject).runWhenProjectIsInitialized(runnable);
}
public void closeContent(Content content) {
@@ -22,8 +22,6 @@ import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowType;
import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
import com.intellij.openapi.wm.impl.DesktopLayout;
@@ -51,9 +49,8 @@ public class HideAllToolWindowsAction extends AnAction implements DumbAware {
String[] ids = toolWindowManager.getToolWindowIds();
boolean hasVisible = false;
for (String id : ids) {
ToolWindow toolWindow = toolWindowManager.getToolWindow(id);
if (toolWindow.isVisible() && toolWindow.getType() != ToolWindowType.WINDOWED) {
toolWindow.hide(null);
if (HideToolWindowAction.shouldBeHiddenByShortCut(toolWindowManager, id)) {
toolWindowManager.getToolWindow(id).hide(null);
hasVisible = true;
}
}
@@ -82,8 +79,7 @@ public class HideAllToolWindowsAction extends AnAction implements DumbAware {
ToolWindowManagerEx toolWindowManager = ToolWindowManagerEx.getInstanceEx(project);
String[] ids = toolWindowManager.getToolWindowIds();
for (String id : ids) {
ToolWindow toolWindow = toolWindowManager.getToolWindow(id);
if (toolWindow.isVisible() && toolWindow.getType() != ToolWindowType.WINDOWED) {
if (HideToolWindowAction.shouldBeHiddenByShortCut(toolWindowManager, id)) {
presentation.setEnabled(true);
presentation.setText(IdeBundle.message("action.hide.all.windows"), true);
return;
@@ -21,7 +21,6 @@ import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ex.ToolWindowEx;
import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
public class HideSideWindowsAction extends AnAction implements DumbAware {
@@ -37,7 +36,9 @@ public class HideSideWindowsAction extends AnAction implements DumbAware {
if (id == null) {
id = toolWindowManager.getLastActiveToolWindowId();
}
toolWindowManager.hideToolWindow(id, true);
if (HideToolWindowAction.shouldBeHiddenByShortCut(toolWindowManager, id)) {
toolWindowManager.hideToolWindow(id, true);
}
}
public void update(AnActionEvent event) {
@@ -60,8 +61,6 @@ public class HideSideWindowsAction extends AnAction implements DumbAware {
presentation.setEnabled(false);
return;
}
ToolWindowEx toolWindow = (ToolWindowEx)toolWindowManager.getToolWindow(id);
presentation.setEnabled(toolWindow.isVisible());
presentation.setEnabled(HideToolWindowAction.shouldBeHiddenByShortCut(toolWindowManager, id));
}
}
@@ -18,12 +18,14 @@ package com.intellij.ide.actions;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowType;
import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class HideToolWindowAction extends AnAction implements DumbAware {
public void actionPerformed(AnActionEvent e) {
@@ -37,7 +39,15 @@ public class HideToolWindowAction extends AnAction implements DumbAware {
if (id == null) {
id = toolWindowManager.getLastActiveToolWindowId();
}
toolWindowManager.getToolWindow(id).hide(null);
if (shouldBeHiddenByShortCut(toolWindowManager, id)) {
toolWindowManager.getToolWindow(id).hide(null);
}
}
static boolean shouldBeHiddenByShortCut(@NotNull ToolWindowManagerEx manager, @Nullable String id) {
if (id == null) return false;
ToolWindow window = manager.getToolWindow(id);
return window.isVisible() && window.getType() != ToolWindowType.WINDOWED;
}
public void update(AnActionEvent event) {
@@ -50,18 +60,9 @@ public class HideToolWindowAction extends AnAction implements DumbAware {
ToolWindowManagerEx toolWindowManager = ToolWindowManagerEx.getInstanceEx(project);
String id = toolWindowManager.getActiveToolWindowId();
if (id != null) {
presentation.setEnabled(true);
return;
}
id = toolWindowManager.getLastActiveToolWindowId();
if (id == null) {
presentation.setEnabled(false);
return;
id = toolWindowManager.getLastActiveToolWindowId();
}
ToolWindow toolWindow = toolWindowManager.getToolWindow(id);
presentation.setEnabled(toolWindow.isVisible());
presentation.setEnabled(shouldBeHiddenByShortCut(toolWindowManager, id));
}
}
@@ -135,7 +135,8 @@ Button.darcula.disabledText.shadow=00000000
ToggleButton.border=com.intellij.ide.ui.laf.darcula.ui.DarculaButtonPainter
ToggleButtonUI=com.intellij.ide.ui.laf.darcula.ui.DarculaButtonUI
MenuItem.acceleratorForeground=eeeeee
MenuItem.acceleratorForeground=bbbbbb
MenuItem.acceleratorSelectionForeground=bbbbbb
PopupMenu.translucentBackground=3c3f41
ToolTip.background=5C5C42
@@ -1,4 +1,3 @@
# suppress inspection "UnusedProperty" for whole file
darcula.selectionBackground=2F65CA
Menu.arrowIcon=AllIcons.Mac.Tree_white_right_arrow
MenuItem.acceleratorSelectionForeground=ffffff
Menu.arrowIcon=AllIcons.Mac.Tree_white_right_arrow
@@ -51,16 +51,6 @@ MenuBar.shadow=cccccc
MenuBar.darcula.borderColor=E8E8E8
MenuBar.darcula.borderShadowColor=A0A0A0
TabbedPaneUI=com.intellij.ide.ui.laf.darcula.ui.DarculaTabbedPaneUI
TabbedPane.tabInsets=0,4,0,4
TabbedPane.highlight=cccccc
TabbedPane.light=444444
TabbedPane.selected=A2BAE0
TabbedPane.selectHighlight=d2d2d2
TabbedPane.contentBorderInsets=3,1,1,1
TabbedPane.darkShadow=cccccc
TabbedPane.shadow=989898
Separator.foreground=cdcdcd
Focus.color=ff0000
@@ -5,3 +5,13 @@ darcula.selectionForeground=bbbbbb
PopupMenu.border=com.intellij.ide.ui.laf.darcula.ui.DarculaPopupMenuBorder
MenuBar.border=com.intellij.ide.ui.laf.darcula.ui.DarculaMenuBarBorder
TabbedPaneUI=com.intellij.ide.ui.laf.darcula.ui.DarculaTabbedPaneUI
TabbedPane.tabInsets=0,4,0,4
TabbedPane.highlight=cccccc
TabbedPane.light=444444
TabbedPane.selected=A2BAE0
TabbedPane.selectHighlight=d2d2d2
TabbedPane.contentBorderInsets=3,1,1,1
TabbedPane.darkShadow=cccccc
TabbedPane.shadow=989898
@@ -31,10 +31,14 @@ RadioButton.border=com.intellij.ide.ui.laf.intellij.MacRadioButtonBorder
ComboBoxUI=com.intellij.ide.ui.laf.intellij.MacIntelliJComboBoxUI
ComboBox.background=ffffff
ComboBox.border=com.intellij.ide.ui.laf.intellij.MacComboBoxBorder
MenuItem.acceleratorSelectionForeground=ffffff
MenuItem.acceleratorSelectionForeground=dcdcdc
PopupMenu.background=f6f6f6
MenuItem.background=f6f6f6
Menu.background=f6f6f6
SplitPane.highlight=ececec
TabbedPane.selectedTabTitlePressedColor=dcdcdc
TabbedPane.selectedTabTitleNormalColor=dcdcdc
@@ -5,6 +5,17 @@ darcula.selectionForeground=ffffff
PopupMenu.border=com.intellij.ide.ui.laf.darcula.ui.DarculaPopupMenuBorder
MenuBar.border=com.intellij.ide.ui.laf.darcula.ui.DarculaMenuBarBorder
TabbedPaneUI=com.intellij.ide.ui.laf.darcula.ui.DarculaTabbedPaneUI
TabbedPane.tabInsets=0,4,0,4
TabbedPane.highlight=cccccc
TabbedPane.light=444444
TabbedPane.selected=A2BAE0
TabbedPane.selectHighlight=d2d2d2
TabbedPane.contentBorderInsets=3,1,1,1
TabbedPane.darkShadow=cccccc
TabbedPane.shadow=989898
#InternalFrameUI=com.intellij.ide.ui.laf.darcula.ui.DarculaInternalFrameUI
#InternalFrame.border=com.intellij.ide.ui.laf.darcula.ui.DarculaInternalBorder
#RootPaneUI=com.intellij.ide.ui.laf.darcula.ui.DarculaRootPaneUI
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -18,7 +18,7 @@ package com.intellij.openapi.fileEditor.impl;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.ui.UISettingsListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.components.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.*;
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
@@ -28,7 +28,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
@@ -40,13 +39,18 @@ import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
public final class EditorHistoryManager extends AbstractProjectComponent implements JDOMExternalizable {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.EditorHistoryManager");
private Element myElement;
@State(name = "editorHistoryManager", storages = @Storage(file = StoragePathMacros.WORKSPACE_FILE))
public final class EditorHistoryManager implements PersistentStateComponent<Element> {
private static final Logger LOG = Logger.getInstance(EditorHistoryManager.class);
public static EditorHistoryManager getInstance(final Project project){
private final Project myProject;
public static EditorHistoryManager getInstance(@NotNull Project project){
return project.getComponent(EditorHistoryManager.class);
}
@@ -55,49 +59,24 @@ public final class EditorHistoryManager extends AbstractProjectComponent impleme
*/
private final List<HistoryEntry> myEntriesList = new ArrayList<HistoryEntry>();
/**
* Invoked by reflection
*/
EditorHistoryManager(final Project project, final UISettings uiSettings) {
super(project);
uiSettings.addUISettingsListener(new MyUISettingsListener(), project);
}
EditorHistoryManager(@NotNull Project project, @NotNull UISettings uiSettings) {
myProject = project;
@Override
public void projectOpened(){
MessageBusConnection connection = myProject.getMessageBus().connect();
connection.subscribe(FileEditorManagerListener.Before.FILE_EDITOR_MANAGER, new MyEditorManagerBeforeListener());
connection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new MyEditorManagerListener());
StartupManager.getInstance(myProject).runWhenProjectIsInitialized(
new DumbAwareRunnable() {
@Override
public void run() {
// myElement may be null if node that corresponds to this manager does not exist
if (myElement != null) {
final List children = myElement.getChildren(HistoryEntry.TAG);
myElement = null;
//noinspection unchecked
for (final Element e : (Iterable<Element>)children) {
try {
addEntry(new HistoryEntry(EditorHistoryManager.this.myProject, e));
}
catch (InvalidDataException e1) {
// OK here
}
catch (ProcessCanceledException e1) {
// OK here
}
catch (Exception anyException) {
LOG.error(anyException);
}
}
trimToSize();
}
}
uiSettings.addUISettingsListener(new UISettingsListener() {
@Override
public void uiSettingsChanged(UISettings source) {
trimToSize();
}
);
}, project);
MessageBusConnection connection = project.getMessageBus().connect();
connection.subscribe(FileEditorManagerListener.Before.FILE_EDITOR_MANAGER, new FileEditorManagerListener.Before.Adapter() {
@Override
public void beforeFileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
updateHistoryEntry(file, false);
}
});
connection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new MyEditorManagerListener());
}
private synchronized void addEntry(HistoryEntry entry) {
@@ -108,16 +87,6 @@ public final class EditorHistoryManager extends AbstractProjectComponent impleme
myEntriesList.remove(entry);
}
@Override
@NotNull
public String getComponentName(){
return "editorHistoryManager";
}
private void fileOpenedImpl(@NotNull final VirtualFile file) {
fileOpenedImpl(file, null, null);
}
/**
* Makes file most recent one
*/
@@ -332,20 +301,42 @@ public final class EditorHistoryManager extends AbstractProjectComponent impleme
}
@Override
public void readExternal(final Element element) {
public void loadState(@NotNull Element element) {
// we have to delay xml processing because history entries require EditorStates to be created
// which is done via corresponding EditorProviders, those are not accessible before their
// is initComponent() called
myElement = element.clone();
final Element state = element.clone();
StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new DumbAwareRunnable() {
@Override
public void run() {
for (Element e : state.getChildren(HistoryEntry.TAG)) {
try {
addEntry(new HistoryEntry(myProject, e));
}
catch (InvalidDataException e1) {
// OK here
}
catch (ProcessCanceledException e1) {
// OK here
}
catch (Exception anyException) {
LOG.error(anyException);
}
}
trimToSize();
}
});
}
@Override
public synchronized void writeExternal(final Element element){
public synchronized Element getState() {
Element element = new Element("state");
// update history before saving
final VirtualFile[] openFiles = FileEditorManager.getInstance(myProject).getOpenFiles();
for (int i = openFiles.length - 1; i >= 0; i--) {
final VirtualFile file = openFiles[i];
if(getEntry(file) != null){ // we have to update only files that are in history
// we have to update only files that are in history
if (getEntry(file) != null) {
updateHistoryEntry(file, false);
}
}
@@ -353,6 +344,7 @@ public final class EditorHistoryManager extends AbstractProjectComponent impleme
for (final HistoryEntry entry : myEntriesList) {
entry.writeExternal(element, myProject);
}
return element;
}
/**
@@ -361,7 +353,7 @@ public final class EditorHistoryManager extends AbstractProjectComponent impleme
private final class MyEditorManagerListener extends FileEditorManagerAdapter{
@Override
public void fileOpened(@NotNull final FileEditorManager source, @NotNull final VirtualFile file){
fileOpenedImpl(file);
fileOpenedImpl(file, null, null);
}
@Override
@@ -377,21 +369,4 @@ public final class EditorHistoryManager extends AbstractProjectComponent impleme
});
}
}
private final class MyEditorManagerBeforeListener extends FileEditorManagerListener.Before.Adapter {
@Override
public void beforeFileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
updateHistoryEntry(file, false);
}
}
/**
* Cuts/extends history length
*/
private final class MyUISettingsListener implements UISettingsListener{
@Override
public void uiSettingsChanged(final UISettings source) {
trimToSize();
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -27,7 +27,6 @@ import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Map;
final class HistoryEntry{
@@ -58,10 +57,7 @@ final class HistoryEntry{
myFile = getVirtualFile(e);
myProvider2State = new HashMap<FileEditorProvider, FileEditorState>();
List providers = e.getChildren(PROVIDER_ELEMENT);
for (final Object provider1 : providers) {
Element _e = (Element)provider1;
for (Element _e : e.getChildren(PROVIDER_ELEMENT)) {
String typeId = _e.getAttributeValue(EDITOR_TYPE_ID_ATTR);
FileEditorProvider provider = FileEditorProviderManager.getInstance().getProvider(typeId);
if (provider == null) {
@@ -76,8 +72,7 @@ final class HistoryEntry{
throw new InvalidDataException();
}
FileEditorState state = provider.readState(stateElement, project, myFile);
putState(provider, state);
putState(provider, provider.readState(stateElement, project, myFile));
}
}
@@ -584,20 +584,14 @@ public class KeymapImpl extends ExternalizableSchemeAdapter implements Keymap {
// Parse first keystroke
KeyStroke firstKeyStroke;
String firstKeyStrokeStr = shortcutElement.getAttributeValue(FIRST_KEYSTROKE_ATTRIBUTE);
if (firstKeyStrokeStr == null) {
throw new InvalidDataException("Attribute '" + FIRST_KEYSTROKE_ATTRIBUTE + "' cannot be null; Action's id=" + id + "; Keymap's name=" + myName);
}
if (skipInserts && firstKeyStrokeStr.contains("INSERT")) continue;
if (firstKeyStrokeStr != null) {
firstKeyStroke = KeyStrokeAdapter.getKeyStroke(firstKeyStrokeStr);
if (firstKeyStroke == null) {
throw new InvalidDataException(
"Cannot parse first-keystroke: '" + firstKeyStrokeStr + "'; " + "Action's id=" + id + "; Keymap's name=" + myName);
}
}
else {
throw new InvalidDataException("Attribute 'first-keystroke' cannot be null; Action's id=" + id + "; Keymap's name=" + myName);
}
KeyStroke firstKeyStroke = KeyStrokeAdapter.getKeyStroke(firstKeyStrokeStr);
if (firstKeyStroke == null) continue; // logged when parsed
// Parse second keystroke
@@ -605,21 +599,19 @@ public class KeymapImpl extends ExternalizableSchemeAdapter implements Keymap {
String secondKeyStrokeStr = shortcutElement.getAttributeValue(SECOND_KEYSTROKE_ATTRIBUTE);
if (secondKeyStrokeStr != null) {
secondKeyStroke = KeyStrokeAdapter.getKeyStroke(secondKeyStrokeStr);
if (secondKeyStroke == null) {
throw new InvalidDataException(
"Wrong second-keystroke: '" + secondKeyStrokeStr + "'; Action's id=" + id + "; Keymap's name=" + myName);
}
if (secondKeyStroke == null) continue; // logged when parsed
}
Shortcut shortcut = new KeyboardShortcut(firstKeyStroke, secondKeyStroke);
ArrayList<Shortcut> shortcuts = id2shortcuts.get(id);
shortcuts.add(shortcut);
}
else if (KEYBOARD_GESTURE_SHORTCUT.equals(shortcutElement.getName())) {
KeyStroke stroke = null;
final String strokeText = shortcutElement.getAttributeValue(KEYBOARD_GESTURE_KEY);
if (strokeText != null) {
stroke = KeyStrokeAdapter.getKeyStroke(strokeText);
if (strokeText == null) {
throw new InvalidDataException("Attribute '" + KEYBOARD_GESTURE_KEY + "' cannot be null; Action's id=" + id + "; Keymap's name=" + myName);
}
KeyStroke stroke = KeyStrokeAdapter.getKeyStroke(strokeText);
if (stroke == null) continue; // logged when parsed
final String modifierText = shortcutElement.getAttributeValue(KEYBOARD_GESTURE_MODIFIER);
KeyboardGestureAction.ModifierType modifier = null;
@@ -630,9 +622,6 @@ public class KeymapImpl extends ExternalizableSchemeAdapter implements Keymap {
modifier = KeyboardGestureAction.ModifierType.hold;
}
if (stroke == null) {
throw new InvalidDataException("Wrong keystroke=" + strokeText + " action id=" + id + " keymap=" + myName);
}
if (modifier == null) {
throw new InvalidDataException("Wrong modifier=" + modifierText + " action id=" + id + " keymap=" + myName);
}
@@ -77,21 +77,32 @@ class PluginUpdateInfoDialog extends AbstractUpdateDialog {
protected void doOKAction() {
super.doOKAction();
ProgressManager.getInstance().run(new Task.Backgroundable(null, IdeBundle.message("progress.downloading.plugins"), true, PerformInBackgroundOption.DEAF) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
UpdateChecker.saveDisabledToUpdatePlugins();
boolean updated = UpdateChecker.installPluginUpdates(myUploadedPlugins, indicator);
if (updated && !myPlatformUpdate) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
PluginManagerMain.notifyPluginsUpdated(null);
}
}, ModalityState.NON_MODAL);
if (myPlatformUpdate) {
ProgressManager.getInstance().run(new Task.Modal(null, IdeBundle.message("progress.downloading.plugins"), true) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
UpdateChecker.saveDisabledToUpdatePlugins();
UpdateChecker.installPluginUpdates(myUploadedPlugins, indicator);
}
}
});
});
}
else {
ProgressManager.getInstance().run(new Task.Backgroundable(null, IdeBundle.message("progress.downloading.plugins"), true, PerformInBackgroundOption.DEAF) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
UpdateChecker.saveDisabledToUpdatePlugins();
boolean updated = UpdateChecker.installPluginUpdates(myUploadedPlugins, indicator);
if (updated) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
PluginManagerMain.notifyPluginsUpdated(null);
}
}, ModalityState.NON_MODAL);
}
}
});
}
}
private class PluginUpdateInfoPanel {
@@ -387,7 +387,23 @@ public final class UpdateChecker {
final UpdateChannel channelToPropose = checkForUpdateResult.getChannelToPropose();
final UpdateChannel updatedChannel = checkForUpdateResult.getUpdatedChannel();
if (newChannelReady(channelToPropose)) {
if (updatedChannel != null) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new UpdateInfoDialog(updatedChannel, enableLink, updateSettings.canUseSecureConnection(), updatedPlugins, incompatiblePlugins).show();
}
};
if (alwaysShowResults) {
runnable.run();
}
else {
String message = IdeBundle.message("updates.ready.message", ApplicationNamesInfo.getInstance().getFullProductName());
showNotification(project, message, runnable, NotificationUniqueType.UPDATE_IN_CHANNEL);
}
}
else if (newChannelReady(channelToPropose)) {
Runnable runnable = new Runnable() {
@Override
public void run() {
@@ -409,23 +425,7 @@ public final class UpdateChecker {
}
else {
String message = IdeBundle.message("updates.new.version.available", ApplicationNamesInfo.getInstance().getFullProductName());
showNotification(project, message, false, runnable, NotificationUniqueType.NEW_CHANNEL);
}
}
else if (updatedChannel != null) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new UpdateInfoDialog(updatedChannel, enableLink, updateSettings.canUseSecureConnection(), updatedPlugins, incompatiblePlugins).show();
}
};
if (alwaysShowResults) {
runnable.run();
}
else {
String message = IdeBundle.message("updates.ready.message", ApplicationNamesInfo.getInstance().getFullProductName());
showNotification(project, message, false, runnable, NotificationUniqueType.UPDATE_IN_CHANNEL);
showNotification(project, message, runnable, NotificationUniqueType.NEW_CHANNEL);
}
}
else if (updatedPlugins != null && !updatedPlugins.isEmpty()) {
@@ -447,7 +447,7 @@ public final class UpdateChecker {
}
}, ", ");
String message = IdeBundle.message("updates.plugins.ready.message", updatedPlugins.size(), plugins);
showNotification(project, message, false, runnable, NotificationUniqueType.PLUGINS_UPDATE);
showNotification(project, message, runnable, NotificationUniqueType.PLUGINS_UPDATE);
}
}
else if (alwaysShowResults) {
@@ -457,7 +457,6 @@ public final class UpdateChecker {
private static void showNotification(@Nullable Project project,
String message,
boolean error,
@Nullable final Runnable runnable,
@Nullable final NotificationUniqueType notificationType) {
if (notificationType != null) {
@@ -478,8 +477,7 @@ public final class UpdateChecker {
}
String title = IdeBundle.message("update.notifications.title");
NotificationType type = error ? NotificationType.ERROR : NotificationType.INFORMATION;
NOTIFICATIONS.createNotification(title, XmlStringUtil.wrapInHtml(message), type, listener).whenExpired(new Runnable() {
NOTIFICATIONS.createNotification(title, XmlStringUtil.wrapInHtml(message), NotificationType.INFORMATION, listener).whenExpired(new Runnable() {
@Override
public void run() {
SHOWN_NOTIFICATION_TYPES.remove(notificationType);
@@ -219,7 +219,7 @@ class UpdateInfoDialog extends AbstractUpdateDialog {
);
myNewVersion.setText(formatVersion(myLatestBuild.getVersion(), myLatestBuild.getNumber().asStringWithoutProductCode()));
if (myPatch != null) {
if (myPatch != null && !StringUtil.isEmptyOrSpaces(myPatch.getSize())) {
myPatchInfo.setText(myPatch.getSize() + " MB");
}
else {
@@ -534,7 +534,7 @@ progress.download.plugins=Download Plugins
button.http.proxy.settings=&HTTP Proxy Settings...
group.vendor=Vendor
plugin.status.installed=Installed
progress.downloading.plugins=Downloading plugins
progress.downloading.plugins=Downloading Plugins
progress.downloading.plugin=Downloading plugin ''{0}''
error.cannot.create.temp.dir=Unable to create temp directory ''{0}''
error.connection.failed.with.http.code.N=Connection failed with HTTP code {0}
@@ -20,7 +20,6 @@
</component>
<component>
<implementation-class>com.intellij.openapi.fileEditor.impl.EditorHistoryManager</implementation-class>
<option name="workspace" value="true"/>
</component>
<component>
<interface-class>com.intellij.openapi.fileEditor.ex.IdeDocumentHistory</interface-class>
@@ -25,12 +25,7 @@ import java.net.URL;
public class InfoReader {
@NotNull
public static UpdatesInfo read(@NotNull String fileName) {
try (InputStream stream = InfoReader.class.getResourceAsStream(fileName)) {
return new UpdatesInfo(JDOMUtil.load(stream));
}
catch (Exception e) {
throw new RuntimeException(e);
}
return read(InfoReader.class.getResource(fileName));
}
@NotNull
@@ -17,7 +17,6 @@ package com.intellij.openapi.fileEditor;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
import com.intellij.openapi.fileEditor.impl.EditorHistoryManager;
import com.intellij.openapi.fileEditor.impl.IdeDocumentHistoryImpl;
import com.intellij.testFramework.EditorTestUtil;
@@ -26,7 +25,6 @@ public class IdeDocumentHistoryFunctionalTest extends HeavyFileEditorManagerTest
public void setUp() throws Exception {
super.setUp();
((IdeDocumentHistoryImpl)IdeDocumentHistory.getInstance(getProject())).projectOpened();
EditorHistoryManager.getInstance(getProject()).projectOpened();
}
public void testNavigateBetweenEditLocations() {
@@ -133,6 +133,7 @@ public class Patches {
/**
* JDK on Mac detects font style for system fonts based only on their name (PostScript name).
* This doesn't work for some fonts which don't use recognizable style suffixes in their names.
* Corresponding JDK request for enhancement - <a href="https://bugs.openjdk.java.net/browse/JDK-8139151">JDK-8139151</a>.
*/
public static final boolean JDK_MAC_FONT_STYLE_DETECTION_WORKAROUND = SystemInfo.isMac;
@@ -1964,25 +1964,32 @@ public class UIUtil {
return null;
}
@NonNls
public static String getCssFontDeclaration(final Font font) {
@Language("HTML")
public static String getCssFontDeclaration(@NotNull Font font) {
return getCssFontDeclaration(font, null, null, null);
}
@Language("HTML")
@NonNls
public static String getCssFontDeclaration(final Font font, @Nullable Color fgColor, @Nullable Color linkColor, @Nullable String liImg) {
URL resource = liImg != null ? SystemInfo.class.getResource(liImg) : null;
public static String getCssFontDeclaration(@NotNull Font font, @Nullable Color fgColor, @Nullable Color linkColor, @Nullable String liImg) {
StringBuilder builder = new StringBuilder().append("<style>\n");
String familyAndSize = "font-family:'" + font.getFamily() + "'; font-size:" + font.getSize() + "pt;";
@NonNls String fontFamilyAndSize = "font-family:'" + font.getFamily() + "'; font-size:" + font.getSize() + "pt;";
@NonNls @Language("HTML")
String body = "body, div, td, p {" + fontFamilyAndSize + " " + (fgColor != null ? "color:#" + ColorUtil.toHex(fgColor)+";" : "") + "}\n" +
"code {font-size:" + font.getSize() + "pt;}\n";
builder.append("body, div, td, p {").append(familyAndSize);
if (fgColor != null) builder.append(" color:#").append(ColorUtil.toHex(fgColor)).append(';');
builder.append("}\n");
builder.append("a {").append(familyAndSize);
if (linkColor != null) builder.append(" color:#").append(ColorUtil.toHex(linkColor)).append(';');
builder.append("}\n");
builder.append("code {font-size:").append(font.getSize()).append("pt;}\n");
URL resource = liImg != null ? SystemInfo.class.getResource(liImg) : null;
if (resource != null) {
body += "ul {list-style-image:url('" + StringUtil.escapeCharCharacters(resource.toExternalForm()) + "');}\n";
builder.append("ul {list-style-image:url('").append(StringUtil.escapeCharCharacters(resource.toExternalForm())).append("');}\n");
}
@NonNls String link = linkColor != null ? "a {" + fontFamilyAndSize + " color:#"+ColorUtil.toHex(linkColor) + ";}\n" : "";
return "<style>\n" + body + link + "</style>";
return builder.append("</style>").toString();
}
public static boolean isWinLafOnVista() {
@@ -33,6 +33,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.plaf.basic.ComboPopup;
import java.awt.*;
/**
@@ -142,8 +143,9 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
@Override
public XExpression getExpression() {
if (myComboBox.isPopupVisible()) {
Object value = myComboBox.getPopup().getList().getSelectedValue();
ComboPopup popup = myComboBox.getPopup();
if (popup != null && popup.isVisible()) {
Object value = popup.getList().getSelectedValue();
if (value != null) {
return (XExpression)value;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -79,14 +79,14 @@ public class GroovyExtractChooser {
throw new GrRefactoringError(RefactoringBundle.message("readonly.occurences.found"));
}
SelectionModel selectionModel = editor.getSelectionModel();
PsiDocumentManager.getInstance(project).commitAllDocuments();
final StringPartInfo stringPart = StringPartInfo.findStringPart(file, selectionModel.getSelectionStart(), selectionModel.getSelectionEnd());
final StringPartInfo stringPart = StringPartInfo.findStringPart(file, start, end);
if (stringPart != null) {
return new InitialInfo(new VariableInfo[0], new VariableInfo[0], PsiElement.EMPTY_ARRAY, GrStatement.EMPTY_ARRAY, new ArrayList<GrStatement>(), stringPart, project, null);
}
final SelectionModel selectionModel = editor.getSelectionModel();
if (!forceStatements) {
GrVariable variable = GrIntroduceHandlerBase.findVariable(file, start, end);
if (variable != null) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -75,7 +75,7 @@ public class GrIntroduceParameterHandler implements RefactoringActionHandler, Me
if (expressions.isEmpty()) {
GrIntroduceHandlerBase.updateSelectionForVariable(editor, file, selectionModel, offset);
}
else if (expressions.size() == 1) {
else if (expressions.size() == 1 || ApplicationManager.getApplication().isUnitTestMode()) {
final TextRange textRange = expressions.get(0).getTextRange();
selectionModel.setSelection(textRange.getStartOffset(), textRange.getEndOffset());
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -404,4 +404,24 @@ def foo(String anObject) {
}
''')
}
void testIntroduceFromStringByCaret() {
doTest IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, null, false, '''\
def test() {
createFile();
}
def createFile() {
new File("na<caret>me").createNewFile()
}
''', '''\
def test() {
createFile("name");
}
def createFile(String anObject) {
new File(anObject).createNewFile()
}
'''
}
}