summaryrefslogtreecommitdiff
path: root/platform/platform-impl/src/com/intellij/ide
diff options
context:
space:
mode:
Diffstat (limited to 'platform/platform-impl/src/com/intellij/ide')
-rw-r--r--platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java6
-rw-r--r--platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java63
-rw-r--r--platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java12
-rw-r--r--platform/platform-impl/src/com/intellij/ide/UiActivityMonitorImpl.java170
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actionMacro/EditMacrosDialog.java37
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actionMacro/actions/EditMacrosAction.java21
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java41
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java11
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java117
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/OpenProjectFileChooserDescriptor.java87
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java115
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/ViewSourceAction.java12
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/AbstractCustomizeWizardStep.java10
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/CustomizeDesktopEntryStep.java108
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java17
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/CustomizeIDEWizardDialog.java22
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/CustomizePluginsStepPanel.java4
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java12
-rw-r--r--platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java65
-rw-r--r--platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java24
-rw-r--r--platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java57
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form43
-rw-r--r--platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java2
23 files changed, 560 insertions, 496 deletions
diff --git a/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java b/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java
index 0aeb20dbda90..c288150bd7ab 100644
--- a/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java
+++ b/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -137,7 +137,9 @@ public class CommandLineProcessor {
if (args.size() > 0) {
String command = args.get(0);
for(ApplicationStarter starter: Extensions.getExtensions(ApplicationStarter.EP_NAME)) {
- if (starter instanceof ApplicationStarterEx && command.equals(starter.getCommandName())) {
+ if (command.equals(starter.getCommandName()) &&
+ starter instanceof ApplicationStarterEx &&
+ ((ApplicationStarterEx)starter).canProcessExternalCommandLine()) {
LOG.info("Processing command with " + starter);
((ApplicationStarterEx) starter).processExternalCommandLine(ArrayUtil.toStringArray(args));
return null;
diff --git a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
index a7d07c9fa1e8..23491c2bdd6a 100644
--- a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
+++ b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
@@ -130,9 +130,9 @@ public class IdeEventQueue extends EventQueue {
private final Set<EventDispatcher> myDispatchers = new LinkedHashSet<EventDispatcher>();
- private final Set<EventDispatcher> myPostprocessors = new LinkedHashSet<EventDispatcher>();
-
+ private final Set<EventDispatcher> myPostProcessors = new LinkedHashSet<EventDispatcher>();
private final Set<Runnable> myReady = new HashSet<Runnable>();
+
private boolean myKeyboardBusy;
private boolean myDispatchingFocusEvent;
@@ -148,16 +148,14 @@ public class IdeEventQueue extends EventQueue {
private IdeEventQueue() {
addIdleTimeCounterRequest();
- final KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
- //noinspection HardCodedStringLiteral
+ final KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
keyboardFocusManager.addPropertyChangeListener("permanentFocusOwner", new PropertyChangeListener() {
@Override
public void propertyChange(final PropertyChangeEvent e) {
final Application application = ApplicationManager.getApplication();
if (application == null) {
-
// We can get focus event before application is initialized
return;
}
@@ -171,6 +169,12 @@ public class IdeEventQueue extends EventQueue {
});
addDispatcher(new WindowsAltSupressor(), null);
+
+ Application app = ApplicationManager.getApplication();
+ if (app != null && app.isUnitTestMode()) {
+ //noinspection AssignmentToStaticFieldFromInstanceMethod
+ ourAppIsLoaded = true;
+ }
}
@@ -289,11 +293,11 @@ public class IdeEventQueue extends EventQueue {
}
public void addPostprocessor(EventDispatcher dispatcher, @Nullable Disposable parent) {
- _addProcessor(dispatcher, parent, myPostprocessors);
+ _addProcessor(dispatcher, parent, myPostProcessors);
}
public void removePostprocessor(EventDispatcher dispatcher) {
- myPostprocessors.remove(dispatcher);
+ myPostProcessors.remove(dispatcher);
}
private static void _addProcessor(final EventDispatcher dispatcher, Disposable parent, final Set<EventDispatcher> set) {
@@ -344,8 +348,26 @@ public class IdeEventQueue extends EventQueue {
}
}
+ private static boolean ourAppIsLoaded = false;
+
+ private static boolean appIsLoaded() {
+ if (ourAppIsLoaded) return true;
+ boolean loaded = IdeaApplication.isLoaded();
+ if (loaded) ourAppIsLoaded = true;
+ return loaded;
+ }
+
@Override
public void dispatchEvent(AWTEvent e) {
+ if (!appIsLoaded()) {
+ try {
+ super.dispatchEvent(e);
+ }
+ catch (Throwable t) {
+ processException(t);
+ }
+ return;
+ }
fixNonEnglishKeyboardLayouts(e);
@@ -362,15 +384,13 @@ public class IdeEventQueue extends EventQueue {
_dispatchEvent(e, false);
}
catch (Throwable t) {
- if (!myToolkitBugsProcessor.process(t)) {
- PluginManager.processException(t);
- }
+ processException(t);
}
finally {
myIsInInputEvent = wasInputEvent;
myCurrentEvent = oldEvent;
- for (EventDispatcher each : myPostprocessors) {
+ for (EventDispatcher each : myPostProcessors) {
each.dispatch(e);
}
@@ -380,6 +400,12 @@ public class IdeEventQueue extends EventQueue {
}
}
+ private void processException(Throwable t) {
+ if (!myToolkitBugsProcessor.process(t)) {
+ PluginManager.processException(t);
+ }
+ }
+
private static void fixNonEnglishKeyboardLayouts(AWTEvent e) {
if (!Registry.is("ide.non.english.keyboard.layout.fix")) return;
if (e instanceof KeyEvent) {
@@ -722,9 +748,7 @@ public class IdeEventQueue extends EventQueue {
super.dispatchEvent(e);
}
catch (Throwable t) {
- if (!myToolkitBugsProcessor.process(t)) {
- PluginManager.processException(t);
- }
+ processException(t);
}
finally {
myDispatchingFocusEvent = false;
@@ -760,7 +784,7 @@ public class IdeEventQueue extends EventQueue {
}
private static boolean typeAheadDispatchToFocusManager(AWTEvent e) {
- if (e instanceof KeyEvent && appIsLoaded()) {
+ if (e instanceof KeyEvent) {
final KeyEvent event = (KeyEvent)e;
if (!event.isConsumed()) {
final IdeFocusManager focusManager = IdeFocusManager.findInstanceByComponent(event.getComponent());
@@ -771,15 +795,6 @@ public class IdeEventQueue extends EventQueue {
return false;
}
- private static boolean ourAppIsLoaded = false;
-
- private static boolean appIsLoaded() {
- if (ourAppIsLoaded) return true;
- boolean loaded = IdeaApplication.isLoaded();
- if (loaded) ourAppIsLoaded = true;
- return loaded;
- }
-
public void flushQueue() {
while (true) {
AWTEvent event = peekEvent();
diff --git a/platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java b/platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java
index d7118949e5de..4a0e11bf5ff9 100644
--- a/platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java
+++ b/platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java
@@ -128,19 +128,23 @@ public class IdeRepaintManager extends RepaintManager {
final Exception exception = new Exception();
StackTraceElement[] stackTrace = exception.getStackTrace();
for (StackTraceElement st : stackTrace) {
- if (repaint && st.getClassName().startsWith("javax.swing.")) {
+ String className = st.getClassName();
+ String methodName = st.getMethodName();
+
+ if (repaint && className.startsWith("javax.swing.")) {
fromSwing = true;
}
- if (repaint && "imageUpdate".equals(st.getMethodName())) {
+ if (repaint && "imageUpdate".equals(methodName)) {
swingKnownNonAwtOperations = true;
}
- if (st.getClassName().startsWith("javax.swing.JEditorPane") && st.getMethodName().equals("read")) {
+ if ("read".equals(methodName) && className.startsWith("javax.swing.JEditorPane") ||
+ "setCharacterAttributes".equals(methodName) && className.startsWith("javax.swing.text.DefaultStyledDocument")) {
swingKnownNonAwtOperations = true;
break;
}
- if ("repaint".equals(st.getMethodName())) {
+ if ("repaint".equals(methodName)) {
repaint = true;
fromSwing = false;
}
diff --git a/platform/platform-impl/src/com/intellij/ide/UiActivityMonitorImpl.java b/platform/platform-impl/src/com/intellij/ide/UiActivityMonitorImpl.java
index c25c68b4bb2b..e9de64905415 100644
--- a/platform/platform-impl/src/com/intellij/ide/UiActivityMonitorImpl.java
+++ b/platform/platform-impl/src/com/intellij/ide/UiActivityMonitorImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -16,7 +16,6 @@
package com.intellij.ide;
import com.intellij.openapi.Disposable;
-import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.ModalityStateListener;
@@ -24,7 +23,6 @@ import com.intellij.openapi.application.impl.LaterInvocator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.BusyObject;
import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.containers.FactoryMap;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
@@ -34,16 +32,16 @@ import javax.swing.*;
import java.util.*;
public class UiActivityMonitorImpl extends UiActivityMonitor implements ModalityStateListener, Disposable {
-
private final FactoryMap<Project, BusyContainer> myObjects = new FactoryMap<Project, BusyContainer>() {
@Override
protected BusyContainer create(Project key) {
if (isEmpty()) {
installListener();
}
- return key == null ? new BusyContainer(key) : new BusyContainer(null) {
+ return key == null ? new BusyContainer(null) : new BusyContainer(null) {
+ @NotNull
@Override
- protected BusyImpl createBusyImpl(HashSet<UiActivity> key) {
+ protected BusyImpl createBusyImpl(@NotNull Set<UiActivity> key) {
return new BusyImpl(key, this) {
@Override
public boolean isReady() {
@@ -63,7 +61,8 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
private boolean myActive;
- private BusyObject myEmptyBusy = new BusyObject.Impl() {
+ @NotNull
+ private final BusyObject myEmptyBusy = new BusyObject.Impl() {
@Override
public boolean isReady() {
return true;
@@ -84,17 +83,12 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
@Override
public void beforeModalityStateChanged(boolean entering) {
- if (isUnitTestMode()) {
- maybeReady();
- }
- else {
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- maybeReady();
- }
- });
- }
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ maybeReady();
+ }
+ });
}
public void maybeReady() {
@@ -103,15 +97,17 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
}
}
+ @NotNull
@Override
- public BusyObject getBusy(@NotNull Project project, UiActivity... toWatch) {
+ public BusyObject getBusy(@NotNull Project project, @NotNull UiActivity... toWatch) {
if (!isActive()) return myEmptyBusy;
return _getBusy(project, toWatch);
}
+ @NotNull
@Override
- public BusyObject getBusy(UiActivity... toWatch) {
+ public BusyObject getBusy(@NotNull UiActivity... toWatch) {
if (!isActive()) return myEmptyBusy;
return _getBusy(null, toWatch);
@@ -129,10 +125,10 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
if (!isActive()) return;
- invokeLaterIfNeeded(new MyRunnable() {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
- public void run(Throwable allocation) {
- getBusyContainer(project).addActivity(activity, allocation, effectiveModalityState);
+ public void run() {
+ getBusyContainer(project).addActivity(activity, effectiveModalityState);
}
});
}
@@ -141,9 +137,9 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
public void removeActivity(@NotNull final Project project, @NotNull final UiActivity activity) {
if (!isActive()) return;
- invokeLaterIfNeeded(new MyRunnable() {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
- public void run(Throwable allocation) {
+ public void run() {
_getBusy(project).removeActivity(activity);
}
});
@@ -162,10 +158,10 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
public void addActivity(@NotNull final UiActivity activity, @NotNull final ModalityState effectiveModalityState) {
if (!isActive()) return;
- invokeLaterIfNeeded(new MyRunnable() {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
- public void run(Throwable allocation) {
- getBusyContainer(null).addActivity(activity, allocation, effectiveModalityState);
+ public void run() {
+ getBusyContainer(null).addActivity(activity, effectiveModalityState);
}
});
}
@@ -174,15 +170,16 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
public void removeActivity(@NotNull final UiActivity activity) {
if (!isActive()) return;
- invokeLaterIfNeeded(new MyRunnable() {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
- public void run(Throwable allocation) {
+ public void run() {
_getBusy(null).removeActivity(activity);
}
});
}
- private BusyImpl _getBusy(@Nullable Project key, UiActivity... toWatch) {
+ @NotNull
+ private BusyImpl _getBusy(@Nullable Project key, @NotNull UiActivity... toWatch) {
return getBusyContainer(key).getOrCreateBusy(toWatch);
}
@@ -204,6 +201,7 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
return myObjects.get(null);
}
+ @Override
public void clear() {
final Set<Project> keys = myObjects.keySet();
for (Project each : keys) {
@@ -215,7 +213,7 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
public void setActive(boolean active) {
if (myActive == active) return;
- if (myActive && !active) {
+ if (myActive) {
clear();
}
@@ -227,25 +225,19 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
}
private static class ActivityInfo {
- private final Throwable myAllocation;
private final ModalityState myEffectiveState;
- private ActivityInfo(@Nullable Throwable allocation, @NotNull ModalityState effectiveState) {
- myAllocation = allocation;
+ private ActivityInfo(@NotNull ModalityState effectiveState) {
myEffectiveState = effectiveState;
}
- @Nullable
- public Throwable getAllocation() {
- return myAllocation;
- }
-
@NotNull
public ModalityState getEffectiveState() {
return myEffectiveState;
}
}
+ @NotNull
protected ModalityState getCurrentState() {
return ModalityState.current();
}
@@ -258,9 +250,9 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
protected final Set<UiActivity> myToWatch;
protected final UiActivity[] myToWatchArray;
- private UiActivityMonitorImpl.BusyContainer myContainer;
+ private final UiActivityMonitorImpl.BusyContainer myContainer;
- private BusyImpl(Set<UiActivity> toWatch, BusyContainer container) {
+ private BusyImpl(@NotNull Set<UiActivity> toWatch, @NotNull BusyContainer container) {
myToWatch = toWatch;
myToWatchArray = toWatch.toArray(new UiActivity[toWatch.size()]);
myContainer = container;
@@ -274,9 +266,7 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
boolean isOwnReady() {
Map<UiActivity, ActivityInfo> infoToCheck = new HashMap<UiActivity, ActivityInfo>();
- final Iterator<Set<UiActivity>> activitySets = myContainer.myActivities2Object.keySet().iterator();
- while (activitySets.hasNext()) {
- Set<UiActivity> eachActivitySet = activitySets.next();
+ for (Set<UiActivity> eachActivitySet : myContainer.myActivities2Object.keySet()) {
final BusyImpl eachBusyObject = myContainer.myActivities2Object.get(eachActivitySet);
if (eachBusyObject == this) continue;
@@ -304,19 +294,16 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
return true;
}
+ public void addActivity(@NotNull UiActivity activity, @NotNull ModalityState effectiveModalityState) {
+ if (!myToWatch.isEmpty() && !myToWatch.contains(activity)) return;
- public void addActivity(UiActivity activity, Throwable allocation, ModalityState effectiveModalityState) {
- if (!myToWatch.isEmpty()) {
- if (!myToWatch.contains(activity)) return;
- }
-
- myActivities.put(activity, new ActivityInfo(allocation, effectiveModalityState));
+ myActivities.put(activity, new ActivityInfo(effectiveModalityState));
myQueuedToRemove.remove(activity);
- myContainer.onActivityAdded(this, activity);
+ myContainer.onActivityAdded(activity);
}
- public void removeActivity(final UiActivity activity) {
+ public void removeActivity(@NotNull final UiActivity activity) {
if (!myActivities.containsKey(activity)) return;
myQueuedToRemove.add(activity);
@@ -333,87 +320,48 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
onReady();
}
};
- if (isUnitTestMode()) {
- runnable.run();
- }
- else {
- SwingUtilities.invokeLater(runnable);
- }
+ SwingUtilities.invokeLater(runnable);
}
-
- public void clear() {
- UiActivity[] activities = myActivities.keySet().toArray(new UiActivity[myActivities.size()]);
- for (UiActivity each : activities) {
- removeActivity(each);
- }
- }
- }
-
- private static void invokeLaterIfNeeded(final MyRunnable runnable) {
- final Throwable allocation = Registry.is("ide.debugMode") ? new Exception() : null;
-
- if (isUnitTestMode()) {
- runnable.run(allocation);
- }
- else {
- UIUtil.invokeLaterIfNeeded(new Runnable() {
- @Override
- public void run() {
- runnable.run(allocation);
- }
- });
- }
- }
-
- private interface MyRunnable {
- void run(Throwable allocation);
- }
-
- private static boolean isUnitTestMode() {
- Application app = ApplicationManager.getApplication();
- return app == null || app.isUnitTestMode();
}
public class BusyContainer implements Disposable {
+ private final Map<Set<UiActivity>, BusyImpl> myActivities2Object = new HashMap<Set<UiActivity>, BusyImpl>();
+ private final Map<BusyImpl, Set<UiActivity>> myObject2Activities = new HashMap<BusyImpl, Set<UiActivity>>();
- private Map<Set<UiActivity>, BusyImpl> myActivities2Object = new HashMap<Set<UiActivity>, BusyImpl>();
- private Map<BusyImpl, Set<UiActivity>> myObject2Activities = new HashMap<BusyImpl, Set<UiActivity>>();
-
- private Set<UiActivity> myActivities = new HashSet<UiActivity>();
-
- private BusyImpl myDefault;
+ private final Set<UiActivity> myActivities = new HashSet<UiActivity>();
private boolean myRemovingActivityNow;
@Nullable private final Project myProject;
public BusyContainer(@Nullable Project project) {
myProject = project;
- myDefault = registerBusyObject(new HashSet<UiActivity>());
+ registerBusyObject(new HashSet<UiActivity>());
if (project != null) {
Disposer.register(project, this);
}
}
- public BusyImpl getOrCreateBusy(UiActivity... activities) {
- final HashSet<UiActivity> key = new HashSet<UiActivity>();
+ @NotNull
+ public BusyImpl getOrCreateBusy(@NotNull UiActivity... activities) {
+ Set<UiActivity> key = new HashSet<UiActivity>();
key.addAll(Arrays.asList(activities));
if (myActivities2Object.containsKey(key)) {
return myActivities2Object.get(key);
}
- else {
- return registerBusyObject(key);
- }
+ return registerBusyObject(key);
}
- private BusyImpl registerBusyObject(HashSet<UiActivity> key) {
+ @NotNull
+ private BusyImpl registerBusyObject(@NotNull Set<UiActivity> key) {
final BusyImpl busy = createBusyImpl(key);
myActivities2Object.put(key, busy);
myObject2Activities.put(busy, key);
return busy;
}
- protected BusyImpl createBusyImpl(HashSet<UiActivity> key) {
+ @NotNull
+ protected BusyImpl createBusyImpl(@NotNull Set<UiActivity> key) {
return new BusyImpl(key, this);
}
@@ -437,11 +385,11 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
}
}
- public void onActivityAdded(BusyImpl busy, UiActivity activity) {
+ public void onActivityAdded(@NotNull UiActivity activity) {
myActivities.add(activity);
}
- public void onActivityRemoved(BusyImpl busy, UiActivity activity) {
+ public void onActivityRemoved(@NotNull BusyImpl busy, @NotNull UiActivity activity) {
if (myRemovingActivityNow) return;
final Map<BusyImpl, Set<UiActivity>> toRemove = new HashMap<BusyImpl, Set<UiActivity>>();
@@ -450,9 +398,7 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
myRemovingActivityNow = true;
myActivities.remove(activity);
- final Iterator<BusyImpl> objects = myObject2Activities.keySet().iterator();
- while (objects.hasNext()) {
- BusyImpl each = objects.next();
+ for (BusyImpl each : myObject2Activities.keySet()) {
if (each != busy) {
each.removeActivity(activity);
}
@@ -472,11 +418,11 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
}
}
- public void addActivity(UiActivity activity, Throwable allocation, ModalityState state) {
+ public void addActivity(@NotNull UiActivity activity, @NotNull ModalityState state) {
getOrCreateBusy(activity);
final Set<BusyImpl> busies = myObject2Activities.keySet();
for (BusyImpl each : busies) {
- each.addActivity(activity, allocation, state);
+ each.addActivity(activity, state);
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actionMacro/EditMacrosDialog.java b/platform/platform-impl/src/com/intellij/ide/actionMacro/EditMacrosDialog.java
deleted file mode 100644
index 8b2c9acfaef5..000000000000
--- a/platform/platform-impl/src/com/intellij/ide/actionMacro/EditMacrosDialog.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.ide.actionMacro;
-
-import com.intellij.openapi.options.ex.SingleConfigurableEditor;
-import com.intellij.openapi.project.Project;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Created by IntelliJ IDEA.
- * User: max
- * Date: Jul 22, 2003
- * Time: 3:30:56 PM
- * To change this template use Options | File Templates.
- */
-public class EditMacrosDialog extends SingleConfigurableEditor {
- public EditMacrosDialog(@Nullable Project project) {
- super(project, new ActionMacroConfigurable());
- }
-
- protected String getDimensionServiceKey(){
- return "#com.intellij.ide.actionMacro.EditMacrosDialog";
- }
-}
diff --git a/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/EditMacrosAction.java b/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/EditMacrosAction.java
index cb0d0ffd4619..c46241d1c4d9 100644
--- a/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/EditMacrosAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/EditMacrosAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -16,29 +16,22 @@
package com.intellij.ide.actionMacro.actions;
import com.intellij.ide.actionMacro.ActionMacro;
+import com.intellij.ide.actionMacro.ActionMacroConfigurable;
import com.intellij.ide.actionMacro.ActionMacroManager;
-import com.intellij.ide.actionMacro.EditMacrosDialog;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.DumbAware;
-/**
- * Created by IntelliJ IDEA.
- * User: max
- * Date: Jul 22, 2003
- * Time: 3:33:04 PM
- * To change this template use Options | File Templates.
- */
public class EditMacrosAction extends AnAction implements DumbAware {
+ @Override
public void actionPerformed(AnActionEvent e) {
- EditMacrosDialog dialog = new EditMacrosDialog(CommonDataKeys.PROJECT.getData(e.getDataContext()));
- dialog.show();
+ ShowSettingsUtil.getInstance().editConfigurable(e.getProject(), "#com.intellij.ide.actionMacro.EditMacrosDialog", new ActionMacroConfigurable());
}
+ @Override
public void update(AnActionEvent e) {
- final ActionMacroManager manager = ActionMacroManager.getInstance();
- ActionMacro[] macros = manager.getAllMacros();
+ ActionMacro[] macros = ActionMacroManager.getInstance().getAllMacros();
e.getPresentation().setEnabled(macros != null && macros.length > 0);
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java b/platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java
index 1c7855d2eedb..709c3b458112 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java
@@ -19,7 +19,9 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.DumbAware;
import com.intellij.pom.Navigatable;
import com.intellij.pom.NavigatableWithText;
+import com.intellij.pom.PomTargetPsiElement;
import com.intellij.util.OpenSourceUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class BaseNavigateToSourceAction extends AnAction implements DumbAware {
@@ -37,7 +39,7 @@ public abstract class BaseNavigateToSourceAction extends AnAction implements Dum
public void update(AnActionEvent event) {
DataContext dataContext = event.getDataContext();
- final Navigatable target = getTarget(dataContext);
+ final Navigatable target = findTargetForUpdate(dataContext);
boolean enabled = target != null;
if (ActionPlaces.isPopupPlace(event.getPlace())) {
event.getPresentation().setVisible(enabled);
@@ -49,36 +51,21 @@ public abstract class BaseNavigateToSourceAction extends AnAction implements Dum
else {
event.getPresentation().setEnabled(enabled);
}
- if (target != null && target instanceof NavigatableWithText) {
- //as myFocusEditor is always ignored - Main Menu|View always contains 2 actions with the same name and actually same behaviour
- if (!myFocusEditor) {
- event.getPresentation().setVisible(false);
- return;
- }
- final String navigateActionText = ((NavigatableWithText)target).getNavigateActionText(myFocusEditor);
- if (navigateActionText != null) {
- event.getPresentation().setText(navigateActionText);
- }
- else {
- event.getPresentation().setText(getTemplatePresentation().getText());
- }
- }
- else {
- event.getPresentation().setText(getTemplatePresentation().getText());
- }
+ //as myFocusEditor is always ignored - Main Menu|View always contains 2 actions with the same name and actually same behaviour
+ event.getPresentation().setVisible(target == null || myFocusEditor);
+ String navigateActionText = myFocusEditor && target instanceof NavigatableWithText?
+ ((NavigatableWithText)target).getNavigateActionText(true) : null;
+ event.getPresentation().setText(navigateActionText == null ? getTemplatePresentation().getText() : navigateActionText);
}
@Nullable
- private Navigatable getTarget(final DataContext dataContext) {
- if (!myFocusEditor && CommonDataKeys.EDITOR.getData(dataContext) != null) {
- // makes no sense in editor and conflicts with another action there (ctrl+enter)
- return null;
- }
-
+ private Navigatable findTargetForUpdate(@NotNull DataContext dataContext) {
Navigatable[] navigatables = getNavigatables(dataContext);
- if (navigatables != null) {
- for (Navigatable navigatable : navigatables) {
- if (navigatable.canNavigate()) return navigatable;
+ if (navigatables == null) return null;
+
+ for (Navigatable navigatable : navigatables) {
+ if (navigatable.canNavigate()) {
+ return navigatable instanceof PomTargetPsiElement ? ((PomTargetPsiElement)navigatable).getTarget() : navigatable;
}
}
return null;
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java
index 9bdc5948cffe..136f4b166e1a 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java
@@ -23,6 +23,7 @@ import com.intellij.notification.Notifications;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.application.ApplicationBundle;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -104,11 +105,15 @@ public class CreateDesktopEntryAction extends DumbAwareAction {
final String message = ApplicationBundle.message("desktop.entry.success",
ApplicationNamesInfo.getInstance().getProductName());
- Notifications.Bus.notify(
- new Notification(Notifications.SYSTEM_MESSAGES_GROUP_ID, "Desktop entry created", message, NotificationType.INFORMATION)
- );
+ if (ApplicationManager.getApplication() != null) {
+ Notifications.Bus
+ .notify(new Notification(Notifications.SYSTEM_MESSAGES_GROUP_ID, "Desktop entry created", message, NotificationType.INFORMATION));
+ }
}
catch (Exception e) {
+ if (ApplicationManager.getApplication() == null) {
+ throw new RuntimeException(e);
+ }
final String message = e.getMessage();
if (!StringUtil.isEmptyOrSpaces(message)) {
LOG.warn(e);
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java b/platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java
index 4cabfe9b5fe9..37b09394dd89 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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,14 +19,14 @@ import com.intellij.ide.IdeBundle;
import com.intellij.ide.impl.ProjectUtil;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
-import com.intellij.openapi.fileChooser.FileElement;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileChooser.PathChooserDialog;
import com.intellij.openapi.fileChooser.impl.FileChooserUtil;
import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.FileEditorProvider;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager;
import com.intellij.openapi.fileTypes.FileType;
@@ -34,7 +34,6 @@ import com.intellij.openapi.fileTypes.ex.FileTypeChooser;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -47,54 +46,20 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
public class OpenFileAction extends AnAction implements DumbAware {
+ @Override
public void actionPerformed(AnActionEvent e) {
- @Nullable final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
+ final Project project = e.getProject();
final boolean showFiles = project != null || PlatformProjectOpenProcessor.getInstanceIfItExists() != null;
+ final FileChooserDescriptor descriptor = showFiles ? new ProjectOrFileChooserDescriptor() : new ProjectOnlyFileChooserDescriptor();
+ descriptor.putUserData(PathChooserDialog.PREFER_LAST_OVER_EXPLICIT, showFiles);
- final FileChooserDescriptor descriptor = new OpenProjectFileChooserDescriptor(true) {
- @Override
- public boolean isFileSelectable(VirtualFile file) {
- if (super.isFileSelectable(file)) {
- return true;
- }
- if (file.isDirectory()) {
- return false;
- }
- return showFiles && !FileElement.isArchive(file);
- }
-
- @Override
- public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
- if (!file.isDirectory() && isFileSelectable(file)) {
- if (!showHiddenFiles && FileElement.isFileHidden(file)) return false;
- return true;
- }
- return super.isFileVisible(file, showHiddenFiles);
- }
-
- @Override
- public boolean isChooseMultiple() {
- return showFiles;
- }
- };
- descriptor.setTitle(showFiles ? "Open File or Project" : "Open Project");
-
- VirtualFile userHomeDir = null;
- if (SystemInfo.isUnix) {
- userHomeDir = VfsUtil.getUserHomeDir();
- }
-
- descriptor.putUserData(PathChooserDialog.PREFER_LAST_OVER_EXPLICIT, Boolean.TRUE);
-
- FileChooser.chooseFiles(descriptor, project, userHomeDir, new Consumer<List<VirtualFile>>() {
+ FileChooser.chooseFiles(descriptor, project, VfsUtil.getUserHomeDir(), new Consumer<List<VirtualFile>>() {
@Override
public void consume(final List<VirtualFile> files) {
for (VirtualFile file : files) {
- if (!descriptor.isFileSelectable(file)) { // on Mac, it could be selected anyway
- Messages.showInfoMessage(project,
- file.getPresentableUrl() + " contains no " +
- ApplicationNamesInfo.getInstance().getFullProductName() + " project",
- "Cannot Open Project");
+ if (!descriptor.isFileSelectable(file)) {
+ String message = IdeBundle.message("error.dir.contains.no.project", file.getPresentableUrl());
+ Messages.showInfoMessage(project, message, IdeBundle.message("title.cannot.open.project"));
return;
}
}
@@ -103,9 +68,8 @@ public class OpenFileAction extends AnAction implements DumbAware {
});
}
- private static void doOpenFile(@Nullable final Project project,
- @NotNull final List<VirtualFile> result) {
- for (final VirtualFile file : result) {
+ private static void doOpenFile(@Nullable Project project, @NotNull List<VirtualFile> result) {
+ for (VirtualFile file : result) {
if (file.isDirectory()) {
Project openedProject;
if (ProjectAttachProcessor.canAttachToProject()) {
@@ -118,9 +82,8 @@ public class OpenFileAction extends AnAction implements DumbAware {
return;
}
- if (OpenProjectFileChooserDescriptor.isProjectFile(file) &&
- // if the ipr-based project is already open, just open the ipr file
- (project == null || !file.equals(project.getProjectFile()))) {
+ // try to open as a project - unless the file is an .ipr of the current one
+ if ((project == null || !file.equals(project.getProjectFile())) && OpenProjectFileChooserDescriptor.isProjectFile(file)) {
Project openedProject = ProjectUtil.openOrImport(file.getPath(), project, false);
if (openedProject != null) {
FileChooserUtil.setLastOpenedFile(openedProject, file);
@@ -143,26 +106,54 @@ public class OpenFileAction extends AnAction implements DumbAware {
}
}
- public static void openFile(final String filePath, final Project project) {
- final VirtualFile file = LocalFileSystem.getInstance().findFileByPath(filePath);
+ public static void openFile(String filePath, @NotNull Project project) {
+ VirtualFile file = LocalFileSystem.getInstance().findFileByPath(filePath);
if (file != null && file.isValid()) {
openFile(file, project);
}
}
- public static void openFile(final VirtualFile virtualFile, final Project project) {
- FileEditorProviderManager editorProviderManager = FileEditorProviderManager.getInstance();
- if (editorProviderManager.getProviders(project, virtualFile).length == 0) {
- Messages.showMessageDialog(project,
- IdeBundle.message("error.files.of.this.type.cannot.be.opened",
- ApplicationNamesInfo.getInstance().getProductName()),
- IdeBundle.message("title.cannot.open.file"),
- Messages.getErrorIcon());
+ public static void openFile(VirtualFile file, @NotNull Project project) {
+ FileEditorProvider[] providers = FileEditorProviderManager.getInstance().getProviders(project, file);
+ if (providers.length == 0) {
+ String message = IdeBundle.message("error.files.of.this.type.cannot.be.opened", ApplicationNamesInfo.getInstance().getProductName());
+ Messages.showErrorDialog(project, message, IdeBundle.message("title.cannot.open.file"));
return;
}
- OpenFileDescriptor descriptor = new OpenFileDescriptor(project, virtualFile);
+ OpenFileDescriptor descriptor = new OpenFileDescriptor(project, file);
FileEditorManager.getInstance(project).openTextEditor(descriptor, true);
}
+ private static class ProjectOnlyFileChooserDescriptor extends OpenProjectFileChooserDescriptor {
+ public ProjectOnlyFileChooserDescriptor() {
+ super(true);
+ setTitle(IdeBundle.message("title.open.project"));
+ }
+ }
+
+ // vanilla OpenProjectFileChooserDescriptor only accepts project files; this on is overridden to accept any files
+ private static class ProjectOrFileChooserDescriptor extends OpenProjectFileChooserDescriptor {
+ private final FileChooserDescriptor myStandardDescriptor = FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor();
+
+ public ProjectOrFileChooserDescriptor() {
+ super(true);
+ setTitle(IdeBundle.message("title.open.file.or.project"));
+ }
+
+ @Override
+ public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
+ return file.isDirectory() ? super.isFileVisible(file, showHiddenFiles) : myStandardDescriptor.isFileVisible(file, showHiddenFiles);
+ }
+
+ @Override
+ public boolean isFileSelectable(VirtualFile file) {
+ return file.isDirectory() ? super.isFileSelectable(file) : myStandardDescriptor.isFileSelectable(file);
+ }
+
+ @Override
+ public boolean isChooseMultiple() {
+ return true;
+ }
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/OpenProjectFileChooserDescriptor.java b/platform/platform-impl/src/com/intellij/ide/actions/OpenProjectFileChooserDescriptor.java
index 51d6362b36d8..b462fcbc11ad 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/OpenProjectFileChooserDescriptor.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/OpenProjectFileChooserDescriptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,74 +15,91 @@
*/
package com.intellij.ide.actions;
-import com.intellij.icons.AllIcons;
import com.intellij.ide.highlighter.ProjectFileType;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
-import com.intellij.openapi.fileChooser.FileElement;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.projectImport.ProjectOpenProcessor;
-import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
+/**
+ * Intended for use in actions related to opening or importing existing projects.
+ * <strong>Due to a high I/O impact SHOULD NOT be used in any other cases.</strong>
+ */
public class OpenProjectFileChooserDescriptor extends FileChooserDescriptor {
private static final Icon ourProjectIcon = IconLoader.getIcon(ApplicationInfoEx.getInstanceEx().getSmallIconUrl());
- public OpenProjectFileChooserDescriptor(final boolean chooseFiles) {
+ public OpenProjectFileChooserDescriptor(boolean chooseFiles) {
super(chooseFiles, true, chooseFiles, chooseFiles, false, false);
}
- public boolean isFileSelectable(final VirtualFile file) {
- if (file == null) return false;
+ @Override
+ public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
+ return super.isFileVisible(file, showHiddenFiles) && (file.isDirectory() || isProjectFile(file));
+ }
+
+ @Override
+ public boolean isFileSelectable(VirtualFile file) {
return isProjectDirectory(file) || isProjectFile(file);
}
- public Icon getIcon(final VirtualFile file) {
- if (isProjectDirectory(file)) {
- return dressIcon(file, ourProjectIcon);
- }
- final Icon icon = getImporterIcon(file);
- if (icon != null) {
- return dressIcon(file, icon);
+ @Override
+ public Icon getIcon(VirtualFile file) {
+ if (canInspectDirectory(file)) {
+ if (isIprFile(file) || isIdeaDirectory(file)) {
+ return dressIcon(file, ourProjectIcon);
+ }
+ Icon icon = getImporterIcon(file);
+ if (icon != null) {
+ return dressIcon(file, icon);
+ }
}
return super.getIcon(file);
}
- @Nullable
- private static Icon getImporterIcon(final VirtualFile virtualFile) {
- final ProjectOpenProcessor provider = ProjectOpenProcessor.getImportProvider(virtualFile);
+ private static boolean canInspectDirectory(VirtualFile file) {
+ if (file.getParent() == null) return false;
+
+ VirtualFile home = VfsUtil.getUserHomeDir();
+ if (home == null) return false; // unnatural situation
+ VirtualFile homes = home.getParent();
+ if (homes == null) return false; // another one
+ if (homes.equals(file.getParent()) || VfsUtilCore.isAncestor(file, homes, false)) return false;
+
+ return true;
+ }
+
+ private static Icon getImporterIcon(VirtualFile file) {
+ ProjectOpenProcessor provider = ProjectOpenProcessor.getImportProvider(file);
if (provider != null) {
- return virtualFile.isDirectory() && provider.lookForProjectsInDirectory() ? AllIcons.Nodes.IdeaModule : provider.getIcon(virtualFile);
+ return file.isDirectory() && provider.lookForProjectsInDirectory() ? ourProjectIcon : provider.getIcon(file);
}
return null;
}
- public boolean isFileVisible(final VirtualFile file, final boolean showHiddenFiles) {
- if (!showHiddenFiles && FileElement.isFileHidden(file)) return false;
- return isProjectFile(file) || super.isFileVisible(file, showHiddenFiles) && file.isDirectory();
+ public static boolean isProjectFile(@NotNull VirtualFile file) {
+ return !file.isDirectory() && file.isValid() && (isIprFile(file) || hasImportProvider(file));
}
- public static boolean isProjectFile(final VirtualFile file) {
- if (isIprFile(file)) return true;
- final ProjectOpenProcessor importProvider = ProjectOpenProcessor.getImportProvider(file);
- return importProvider != null;
+ private static boolean isProjectDirectory(@NotNull VirtualFile file) {
+ return file.isDirectory() && file.isValid() && (isIdeaDirectory(file) || hasImportProvider(file));
}
private static boolean isIprFile(VirtualFile file) {
- if ((!file.isDirectory() && file.getName().toLowerCase().endsWith(ProjectFileType.DOT_DEFAULT_EXTENSION))) {
- return true;
- }
- return false;
+ return ProjectFileType.DEFAULT_EXTENSION.equalsIgnoreCase(file.getExtension());
+ }
+
+ private static boolean isIdeaDirectory(VirtualFile file) {
+ return file.findChild(Project.DIRECTORY_STORE_FOLDER) != null;
}
- private static boolean isProjectDirectory(final VirtualFile virtualFile) {
- // the root directory of any drive is never an IDEA project
- if (virtualFile.getParent() == null) return false;
- // NOTE: For performance reasons, it's very important not to iterate through all of the children here.
- if (virtualFile.isDirectory() && virtualFile.isValid() && virtualFile.findChild(Project.DIRECTORY_STORE_FOLDER) != null) return true;
- return false;
+ private static boolean hasImportProvider(VirtualFile file) {
+ return ProjectOpenProcessor.getImportProvider(file) != null;
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java b/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java
index 4df11f7261ca..2c5cc5b02282 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java
@@ -15,23 +15,20 @@
*/
package com.intellij.ide.actions;
+import com.intellij.ide.ui.search.SearchUtil;
+import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.options.Configurable;
-import com.intellij.openapi.options.ConfigurableGroup;
-import com.intellij.openapi.options.SearchableConfigurable;
-import com.intellij.openapi.options.ShowSettingsUtil;
-import com.intellij.openapi.options.ex.ConfigurableExtensionPointUtil;
-import com.intellij.openapi.options.ex.IdeConfigurablesGroup;
-import com.intellij.openapi.options.ex.MixedConfigurableGroup;
-import com.intellij.openapi.options.ex.ProjectConfigurablesGroup;
-import com.intellij.openapi.options.ex.SingleConfigurableEditor;
+import com.intellij.openapi.options.*;
+import com.intellij.openapi.options.ex.*;
+import com.intellij.openapi.options.newEditor.IdeSettingsDialog;
import com.intellij.openapi.options.newEditor.OptionsEditor;
import com.intellij.openapi.options.newEditor.OptionsEditorDialog;
-import com.intellij.openapi.options.newEditor.PreferencesDialog;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.ui.navigation.Place;
import com.intellij.util.ui.update.Activatable;
import com.intellij.util.ui.update.UiNotifyConnector;
import org.jetbrains.annotations.NotNull;
@@ -47,7 +44,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
*/
public class ShowSettingsUtilImpl extends ShowSettingsUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.ShowSettingsUtilImpl");
- private AtomicBoolean myShown = new AtomicBoolean(false);
+ private final AtomicBoolean myShown = new AtomicBoolean(false);
@NotNull
private static Project getProject(@Nullable Project project) {
@@ -55,12 +52,16 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
}
@NotNull
- private static DialogWrapper getDialog(@Nullable Project project, @NotNull ConfigurableGroup[] groups, @Nullable Configurable toSelect) {
+ public static DialogWrapper getDialog(@Nullable Project project, @NotNull ConfigurableGroup[] groups, @Nullable Configurable toSelect) {
+ project = getProject(project);
+ final ConfigurableGroup[] filteredGroups = filterEmptyGroups(groups);
+ if (Registry.is("ide.new.settings.dialog")) {
+ return new IdeSettingsDialog(project, filteredGroups, toSelect);
+ }
+ //noinspection deprecation
return Registry.is("ide.perProjectModality")
- ? new OptionsEditorDialog(getProject(project), filterEmptyGroups(groups), toSelect, true)
- : Registry.is("ide.new.preferences")
- ? new PreferencesDialog(getProject(project), filterEmptyGroups(groups))
- : new OptionsEditorDialog(getProject(project), filterEmptyGroups(groups), toSelect);
+ ? new OptionsEditorDialog(project, filteredGroups, toSelect, true)
+ : new OptionsEditorDialog(project, filteredGroups, toSelect);
}
@NotNull
@@ -73,7 +74,7 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
new ProjectConfigurablesGroup(project),
new IdeConfigurablesGroup()};
- return Registry.is("ide.file.settings.order.new")
+ return Registry.is("ide.new.settings.dialog")
? MixedConfigurableGroup.getGroups(getConfigurables(groups, true))
: groups;
}
@@ -139,41 +140,34 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
@Override
public void showSettingsDialog(@Nullable final Project project, @NotNull final String nameToSelect) {
- ConfigurableGroup[] group = getConfigurableGroups(project, true);
-
+ ConfigurableGroup[] groups = getConfigurableGroups(project, true);
Project actualProject = getProject(project);
- group = filterEmptyGroups(group);
+ groups = filterEmptyGroups(groups);
+ getDialog(actualProject, groups, findPreselectedByDisplayName(nameToSelect, groups)).show();
+ }
- OptionsEditorDialog dialog;
- if (Registry.is("ide.perProjectModality")) {
- dialog = new OptionsEditorDialog(actualProject, group, nameToSelect, true);
- }
- else {
- dialog = new OptionsEditorDialog(actualProject, group, nameToSelect);
+ @Nullable
+ private static Configurable findPreselectedByDisplayName(final String preselectedConfigurableDisplayName, ConfigurableGroup[] groups) {
+ final List<Configurable> all = SearchUtil.expand(groups);
+ for (Configurable each : all) {
+ if (preselectedConfigurableDisplayName.equals(each.getDisplayName())) return each;
}
- dialog.show();
+ return null;
}
public static void showSettingsDialog(@Nullable Project project, final String id2Select, final String filter) {
ConfigurableGroup[] group = getConfigurableGroups(project, true);
- Project actualProject = getProject(project);
-
group = filterEmptyGroups(group);
final Configurable configurable2Select = findConfigurable2Select(id2Select, group);
- final OptionsEditorDialog dialog;
- if (Registry.is("ide.perProjectModality")) {
- dialog = new OptionsEditorDialog(actualProject, group, configurable2Select, true);
- } else {
- dialog = new OptionsEditorDialog(actualProject, group, configurable2Select);
- }
+ final DialogWrapper dialog = getDialog(project, group, configurable2Select);
new UiNotifyConnector.Once(dialog.getContentPane(), new Activatable.Adapter() {
@Override
public void showNotify() {
- final OptionsEditor editor = (OptionsEditor)dialog.getData(OptionsEditor.KEY.getName());
+ final OptionsEditor editor = (OptionsEditor)((DataProvider)dialog).getData(OptionsEditor.KEY.getName());
LOG.assertTrue(editor != null);
editor.select(configurable2Select, filter);
}
@@ -234,37 +228,53 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
@Override
public <T extends Configurable> T findProjectConfigurable(final Project project, final Class<T> confClass) {
+ //noinspection deprecation
return ConfigurableExtensionPointUtil.findProjectConfigurable(project, confClass);
}
@Override
public boolean editConfigurable(Project project, String dimensionServiceKey, @NotNull Configurable configurable) {
- return editConfigurable(null, project, configurable, dimensionServiceKey, null);
+ return editConfigurable(project, dimensionServiceKey, configurable, isWorthToShowApplyButton(configurable));
+ }
+
+ private static boolean isWorthToShowApplyButton(@NotNull Configurable configurable) {
+ return configurable instanceof Place.Navigator ||
+ configurable instanceof Composite ||
+ configurable instanceof TabbedConfigurable;
+ }
+
+ @Override
+ public boolean editConfigurable(Project project, String dimensionServiceKey, @NotNull Configurable configurable, boolean showApplyButton) {
+ return editConfigurable(null, project, configurable, dimensionServiceKey, null, showApplyButton);
}
@Override
public boolean editConfigurable(Project project, Configurable configurable, Runnable advancedInitialization) {
- return editConfigurable(null, project, configurable, createDimensionKey(configurable), advancedInitialization);
+ return editConfigurable(null, project, configurable, createDimensionKey(configurable), advancedInitialization, isWorthToShowApplyButton(configurable));
}
@Override
- public boolean editConfigurable(Component parent, Configurable configurable) {
+ public boolean editConfigurable(@Nullable Component parent, @NotNull Configurable configurable) {
return editConfigurable(parent, configurable, null);
}
@Override
- public boolean editConfigurable(final Component parent, final Configurable configurable, @Nullable final Runnable advancedInitialization) {
- return editConfigurable(parent, null, configurable, createDimensionKey(configurable), advancedInitialization);
+ public boolean editConfigurable(@Nullable Component parent, @NotNull Configurable configurable, @Nullable Runnable advancedInitialization) {
+ return editConfigurable(parent, null, configurable, createDimensionKey(configurable), advancedInitialization, isWorthToShowApplyButton(configurable));
}
- private static boolean editConfigurable(final @Nullable Component parent, @Nullable Project project, final Configurable configurable, final String dimensionKey,
- @Nullable final Runnable advancedInitialization) {
- SingleConfigurableEditor editor;
- if (parent != null) {
- editor = new SingleConfigurableEditor(parent, configurable, dimensionKey);
+ private static boolean editConfigurable(@Nullable Component parent,
+ @Nullable Project project,
+ @NotNull Configurable configurable,
+ String dimensionKey,
+ @Nullable final Runnable advancedInitialization,
+ boolean showApplyButton) {
+ final SingleConfigurableEditor editor;
+ if (parent == null) {
+ editor = new SingleConfigurableEditor(project, configurable, dimensionKey, showApplyButton);
}
else {
- editor = new SingleConfigurableEditor(project, configurable, dimensionKey);
+ editor = new SingleConfigurableEditor(parent, configurable, dimensionKey, showApplyButton);
}
if (advancedInitialization != null) {
new UiNotifyConnector.Once(editor.getContentPane(), new Activatable.Adapter() {
@@ -278,15 +288,14 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
return editor.isOK();
}
- public static String createDimensionKey(Configurable configurable) {
- String displayName = configurable.getDisplayName();
- displayName = displayName.replaceAll("\n", "_").replaceAll(" ", "_");
- return "#" + displayName;
+ @NotNull
+ public static String createDimensionKey(@NotNull Configurable configurable) {
+ return '#' + StringUtil.replaceChar(StringUtil.replaceChar(configurable.getDisplayName(), '\n', '_'), ' ', '_');
}
@Override
- public boolean editConfigurable(Component parent, String dimensionServiceKey,Configurable configurable) {
- return editConfigurable(parent, null, configurable, dimensionServiceKey, null);
+ public boolean editConfigurable(Component parent, String dimensionServiceKey, Configurable configurable) {
+ return editConfigurable(parent, null, configurable, dimensionServiceKey, null, isWorthToShowApplyButton(configurable));
}
public boolean isAlreadyShown() {
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ViewSourceAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ViewSourceAction.java
index a9461422f747..825db992b218 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/ViewSourceAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/ViewSourceAction.java
@@ -17,9 +17,21 @@
package com.intellij.ide.actions;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
public class ViewSourceAction extends BaseNavigateToSourceAction {
public ViewSourceAction() {
super(false);
}
+
+ @Override
+ public void update(AnActionEvent e) {
+ if (CommonDataKeys.EDITOR.getData(e.getDataContext()) != null) {
+ e.getPresentation().setEnabledAndVisible(false);
+ }
+ else {
+ super.update(e);
+ }
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/AbstractCustomizeWizardStep.java b/platform/platform-impl/src/com/intellij/ide/customize/AbstractCustomizeWizardStep.java
index 6844ed5bab25..798247e16186 100644
--- a/platform/platform-impl/src/com/intellij/ide/customize/AbstractCustomizeWizardStep.java
+++ b/platform/platform-impl/src/com/intellij/ide/customize/AbstractCustomizeWizardStep.java
@@ -21,12 +21,14 @@ import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
+import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
public abstract class AbstractCustomizeWizardStep extends JPanel {
+ protected static final int SMALL_GAP = 10;
protected static final int GAP = 20;
protected abstract String getTitle();
@@ -40,6 +42,14 @@ public abstract class AbstractCustomizeWizardStep extends JPanel {
return ColorUtil.mix(UIUtil.getListSelectionBackground(), UIUtil.getLabelBackground(), UIUtil.isUnderDarcula() ? .5 : .75);
}
+ public static Border createSmallEmptyBorder() {
+ return BorderFactory.createEmptyBorder(SMALL_GAP, SMALL_GAP, SMALL_GAP, SMALL_GAP);
+ }
+
+ public static BorderLayout createSmallBorderLayout() {
+ return new BorderLayout(SMALL_GAP, SMALL_GAP);
+ }
+
protected static JPanel createBigButtonPanel(LayoutManager layout, final JToggleButton anchorButton, final Runnable action) {
final JPanel panel = new JPanel(layout) {
@Override
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeDesktopEntryStep.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeDesktopEntryStep.java
new file mode 100644
index 000000000000..57b68232b797
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeDesktopEntryStep.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2000-2014 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.ide.customize;
+
+import com.intellij.ide.actions.CreateDesktopEntryAction;
+import com.intellij.idea.ActionsBundle;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.progress.EmptyProgressIndicator;
+import com.intellij.openapi.util.EmptyRunnable;
+import com.intellij.openapi.util.IconLoader;
+import com.intellij.util.ui.GridBag;
+import com.intellij.util.ui.UIUtil;
+
+import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import java.awt.*;
+
+/**
+ * @author Alexander Lobas
+ */
+public class CustomizeDesktopEntryStep extends AbstractCustomizeWizardStep {
+ private final JCheckBox myCreateEntryCheckBox = new JCheckBox(ActionsBundle.message("action.CreateDesktopEntry.description"));
+ private final JCheckBox myGlobalEntryCheckBox = new JCheckBox("For all users");
+
+ public CustomizeDesktopEntryStep(String iconPath) {
+ setLayout(new BorderLayout());
+
+ JPanel panel = createBigButtonPanel(createSmallBorderLayout(), myCreateEntryCheckBox, EmptyRunnable.INSTANCE);
+ panel.setBorder(createSmallEmptyBorder());
+
+ JPanel buttonPanel = new JPanel(new GridBagLayout());
+ buttonPanel.setOpaque(false);
+
+ GridBag gbc =
+ new GridBag().setDefaultAnchor(GridBagConstraints.WEST).setDefaultFill(GridBagConstraints.HORIZONTAL).setDefaultWeightX(1);
+
+ myCreateEntryCheckBox.setOpaque(false);
+ buttonPanel.add(myCreateEntryCheckBox, gbc.nextLine());
+
+ myGlobalEntryCheckBox.setOpaque(false);
+ gbc.nextLine().insets.left = UIUtil.PANEL_REGULAR_INSETS.left;
+ buttonPanel.add(myGlobalEntryCheckBox, gbc);
+
+ panel.add(buttonPanel, BorderLayout.NORTH);
+
+ JLabel label = new JLabel(IconLoader.getIcon(iconPath));
+ label.setVerticalAlignment(JLabel.TOP);
+ panel.add(label, BorderLayout.CENTER);
+
+ add(panel, BorderLayout.CENTER);
+
+ myCreateEntryCheckBox.addChangeListener(new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ myGlobalEntryCheckBox.setEnabled(myCreateEntryCheckBox.isSelected());
+ myGlobalEntryCheckBox.setSelected(myCreateEntryCheckBox.isSelected() && !PathManager.getHomePath().startsWith("/home"));
+ }
+ });
+
+ myCreateEntryCheckBox.setSelected(true);
+ }
+
+ public static boolean isAvailable() {
+ return CreateDesktopEntryAction.isAvailable();
+ }
+
+ @Override
+ public boolean beforeOkAction() {
+ if (myCreateEntryCheckBox.isSelected()) {
+ try {
+ CreateDesktopEntryAction.createDesktopEntry(null, new EmptyProgressIndicator(), myGlobalEntryCheckBox.isSelected());
+ }
+ catch (Throwable e) {
+ // ignored
+ }
+ }
+ return true;
+ }
+
+ @Override
+ protected String getTitle() {
+ return "Desktop Entry";
+ }
+
+ @Override
+ protected String getHTMLHeader() {
+ return "<html><body><h2>Create Desktop Entry</h2>&nbsp;</body></html>";
+ }
+
+ @Override
+ protected String getHTMLFooter() {
+ return "Desktop entry can be created later in Tools | Create Desktop Entry...";
+ }
+} \ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java
index 786a5825e783..498391b8e971 100644
--- a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java
+++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java
@@ -18,7 +18,9 @@ package com.intellij.ide.customize;
import com.intellij.CommonBundle;
import com.intellij.icons.AllIcons;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
+import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.ide.plugins.PluginNode;
+import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.updateSettings.impl.PluginDownloader;
@@ -78,7 +80,7 @@ public class CustomizeFeaturedPluginsStepPanel extends AbstractCustomizeWizardSt
final String pluginId = s.substring(j + 1);
IdeaPluginDescriptor foundDescriptor = null;
for (IdeaPluginDescriptor descriptor : pluginsFromRepository) {
- if (descriptor.getPluginId().getIdString().equals(pluginId)) {
+ if (descriptor.getPluginId().getIdString().equals(pluginId) && !PluginManagerCore.isBrokenPlugin(descriptor)) {
foundDescriptor = descriptor;
isEmptyOrOffline = false;
break;
@@ -107,11 +109,11 @@ public class CustomizeFeaturedPluginsStepPanel extends AbstractCustomizeWizardSt
JPanel progressPanel = new JPanel(new VerticalFlowLayout(true, false));
progressPanel.add(progressBar);
final LinkLabel cancelLink = new LinkLabel("Cancel", AllIcons.Actions.Cancel);
- JPanel linkWrapper = new JPanel(new FlowLayout(FlowLayout.CENTER));
+ JPanel linkWrapper = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
linkWrapper.add(cancelLink);
progressPanel.add(linkWrapper);
- JPanel buttonPanel = new JPanel(new VerticalFlowLayout());
+ JPanel buttonPanel = new JPanel(new VerticalFlowLayout(0, 0));
buttonPanel.add(installButton);
buttonWrapper.add(buttonPanel, "button");
@@ -218,7 +220,7 @@ public class CustomizeFeaturedPluginsStepPanel extends AbstractCustomizeWizardSt
}, null);
gbc.insets.bottom = -5;
groupPanel.add(titleLabel, gbc);
- gbc.insets.bottom = 10;
+ gbc.insets.bottom = SMALL_GAP;
groupPanel.add(topicLabel, gbc);
groupPanel.add(descriptionLabel, gbc);
gbc.weighty = 1;
@@ -238,7 +240,7 @@ public class CustomizeFeaturedPluginsStepPanel extends AbstractCustomizeWizardSt
protected Color getColor() {
return ColorUtil.withAlpha(JBColor.foreground(), .2);
}
- }, BorderFactory.createEmptyBorder(GAP, GAP, 0, GAP)));
+ }, BorderFactory.createEmptyBorder(0, SMALL_GAP, 0, SMALL_GAP)));
cursor++;
}
@@ -260,7 +262,10 @@ public class CustomizeFeaturedPluginsStepPanel extends AbstractCustomizeWizardSt
@Override
public String getHTMLFooter() {
- return "New plugins can also be downloaded in " + CommonBundle.settingsTitle() + " | Plugins";
+ return "New plugins can also be downloaded in "
+ + CommonBundle.settingsTitle()
+ + " | " + OptionsBundle.message("configurable.group.appearance.settings.display.name")
+ + " | " + "Plugins";
}
public static class OfflineException extends Exception {};
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeIDEWizardDialog.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeIDEWizardDialog.java
index be37f9d9d7f6..af3c193ca9d9 100644
--- a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeIDEWizardDialog.java
+++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeIDEWizardDialog.java
@@ -21,7 +21,7 @@ import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.JBCardLayout;
-import org.jetbrains.annotations.NotNull;
+import com.intellij.util.PlatformUtils;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -51,6 +51,7 @@ public class CustomizeIDEWizardDialog extends DialogWrapper implements ActionLis
public CustomizeIDEWizardDialog() {
super(null, true, true);
setTitle("Customize " + ApplicationNamesInfo.getInstance().getProductName());
+ getPeer().setAppIcons();
initSteps();
mySkipButton.addActionListener(this);
myBackButton.addActionListener(this);
@@ -119,7 +120,7 @@ public class CustomizeIDEWizardDialog extends DialogWrapper implements ActionLis
result.add(myContentPanel, BorderLayout.CENTER);
result.add(myFooterLabel, BorderLayout.SOUTH);
result.setPreferredSize(new Dimension(700, 600));
- result.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+ result.setBorder(AbstractCustomizeWizardStep.createSmallEmptyBorder());
return result;
}
@@ -131,8 +132,10 @@ public class CustomizeIDEWizardDialog extends DialogWrapper implements ActionLis
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
- buttonPanel.add(mySkipButton, gbc);
- gbc.gridx++;
+ if (!PlatformUtils.isCLion()) {
+ buttonPanel.add(mySkipButton, gbc);
+ gbc.gridx++;
+ }
buttonPanel.add(myBackButton, gbc);
gbc.gridx++;
gbc.weightx = 1;
@@ -219,15 +222,4 @@ public class CustomizeIDEWizardDialog extends DialogWrapper implements ActionLis
}
myNavigationLabel.setText(navHTML.toString());
}
-
-
- private static <T extends Component> void getChildren(@NotNull Component c, Class<? extends T> cls, List<T> accumulator) {
- if (cls.isAssignableFrom(c.getClass())) accumulator.add((T)c);
- if (c instanceof Container) {
- Component[] components = ((Container)c).getComponents();
- for (Component component : components) {
- getChildren(component, cls, accumulator);
- }
- }
- }
}
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizePluginsStepPanel.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizePluginsStepPanel.java
index 8924c09780dd..de12269b5887 100644
--- a/platform/platform-impl/src/com/intellij/ide/customize/CustomizePluginsStepPanel.java
+++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizePluginsStepPanel.java
@@ -115,7 +115,7 @@ public class CustomizePluginsStepPanel extends AbstractCustomizeWizardStep imple
gbc.weighty = 1;
groupPanel.add(Box.createVerticalGlue(), gbc);
gbc.weighty = 0;
- JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 5));
+ JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, SMALL_GAP, SMALL_GAP / 2));
buttonsPanel.setOpaque(false);
if (pluginGroups.getSets(group).size() == 1) {
buttonsPanel.add(createLink(SWITCH_COMMAND + ":" + group, getGroupSwitchTextProvider(group)));
@@ -139,7 +139,7 @@ public class CustomizePluginsStepPanel extends AbstractCustomizeWizardStep imple
protected Color getColor() {
return ColorUtil.withAlpha(JBColor.foreground(), .2);
}
- }, BorderFactory.createEmptyBorder(GAP / 2, GAP, GAP / 2, GAP)));
+ }, BorderFactory.createEmptyBorder(SMALL_GAP, GAP, SMALL_GAP, GAP)));
cursor++;
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java
index b369e49f8bca..c7b29ef53827 100644
--- a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java
+++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java
@@ -22,6 +22,7 @@ import com.intellij.ide.ui.laf.darcula.DarculaLaf;
import com.intellij.ide.ui.laf.darcula.DarculaLookAndFeelInfo;
import com.intellij.idea.StartupUtil;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.util.IconUtil;
@@ -46,7 +47,7 @@ public class CustomizeUIThemeStepPanel extends AbstractCustomizeWizardStep {
private Map<String, Icon> myLafNames = new LinkedHashMap<String, Icon>();
public CustomizeUIThemeStepPanel() {
- setLayout(new BorderLayout(10, 10));
+ setLayout(createSmallBorderLayout());
IconLoader.activate();
initLafs();
@@ -65,13 +66,13 @@ public class CustomizeUIThemeStepPanel extends AbstractCustomizeWizardStep {
radioButton.setSelected(true);
myDefaultLafName = lafName;
}
- final JPanel panel = createBigButtonPanel(new BorderLayout(10, 10), radioButton, new Runnable() {
+ final JPanel panel = createBigButtonPanel(createSmallBorderLayout(), radioButton, new Runnable() {
@Override
public void run() {
applyLaf(lafName, CustomizeUIThemeStepPanel.this);
}
});
- panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+ panel.setBorder(createSmallEmptyBorder());
panel.add(radioButton, myColumnMode ? BorderLayout.WEST : BorderLayout.NORTH);
final JLabel label = new JLabel(myColumnMode ? IconUtil.scale(IconUtil.cropIcon(icon, icon.getIconWidth() * 2 / 3, icon.getIconHeight() * 2 / 3), .5) : icon);
label.setVerticalAlignment(SwingConstants.TOP);
@@ -139,7 +140,10 @@ public class CustomizeUIThemeStepPanel extends AbstractCustomizeWizardStep {
@Override
public String getHTMLFooter() {
- return "UI theme can be changed later in " + CommonBundle.settingsTitle() + " | Appearance";
+ return "UI theme can be changed later in " +
+ CommonBundle.settingsTitle()
+ + " | " + OptionsBundle.message("configurable.group.appearance.settings.display.name")
+ + " | " + "Appearance";
}
private void applyLaf(String lafName, Component component) {
diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java
index 6b0b9814698b..de5d67b5e2d8 100644
--- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java
+++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java
@@ -15,6 +15,8 @@
*/
package com.intellij.ide.passwordSafe.impl.providers.masterKey;
+import com.intellij.concurrency.AsyncFutureFactory;
+import com.intellij.concurrency.AsyncFutureResult;
import com.intellij.ide.passwordSafe.MasterPasswordUnavailableException;
import com.intellij.ide.passwordSafe.PasswordSafeException;
import com.intellij.ide.passwordSafe.impl.PasswordSafeTimed;
@@ -23,14 +25,11 @@ import com.intellij.ide.passwordSafe.impl.providers.ByteArrayWrapper;
import com.intellij.ide.passwordSafe.impl.providers.EncryptionUtil;
import com.intellij.ide.passwordSafe.impl.providers.masterKey.windows.WindowsCryptUtils;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.Ref;
-import com.intellij.openapi.util.SystemInfo;
-import com.intellij.openapi.util.ThrowableComputable;
+import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,6 +37,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.ExecutionException;
/**
* The password safe that stores information in configuration file encrypted by master password
@@ -170,12 +170,6 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider {
throw new MasterPasswordUnavailableException("The provider is not available in headless environment");
}
- if (myDatabase.isEmpty()) {
- if (!MasterPasswordDialog.resetMasterPasswordDialog(project, this, requestor).showAndGet()) {
- throw new MasterPasswordUnavailableException("Master password is required to store passwords in the database.");
- }
- }
-
key = invokeAndWait(new ThrowableComputable<Object, PasswordSafeException>() {
@Override
public Object compute() throws PasswordSafeException {
@@ -184,7 +178,14 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider {
return key;
}
try {
- MasterPasswordDialog.askPassword(project, MasterKeyPasswordSafe.this, requestor);
+ if (myDatabase.isEmpty()) {
+ if (!MasterPasswordDialog.resetMasterPasswordDialog(project, MasterKeyPasswordSafe.this, requestor).showAndGet()) {
+ throw new MasterPasswordUnavailableException("Master password is required to store passwords in the database.");
+ }
+ }
+ else {
+ MasterPasswordDialog.askPassword(project, MasterKeyPasswordSafe.this, requestor);
+ }
}
catch (PasswordSafeException e) {
myKey.get().set(e);
@@ -200,35 +201,41 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider {
}
private static final Object ourEDTLock = new Object();
- public <T, E extends Throwable> T invokeAndWait(@NotNull final ThrowableComputable<T, E> computable, @NotNull final Condition expired) throws E {
+ public <T, E extends Throwable> T invokeAndWait(@NotNull final ThrowableComputable<T, E> computable, @NotNull final Condition<?> expired) throws E {
if (ApplicationManager.getApplication().isDispatchThread()) {
return computable.compute();
}
- final Ref<Throwable> exRef = Ref.create();
- final Ref<T> ref = Ref.create();
+
+ final AsyncFutureResult<Object> future = AsyncFutureFactory.getInstance().createAsyncFutureResult();
synchronized (ourEDTLock) {
- if (expired.value(null)) {
- throw new ProcessCanceledException();
- }
- ApplicationManager.getApplication().invokeAndWait(new Runnable() {
+ IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(new ExpirableRunnable() {
@Override
- public void run() {
- if (expired.value(null)) {
- exRef.set(new ProcessCanceledException());
- return;
- }
+ public boolean isExpired() {
+ boolean b = expired.value(null);
+ if (b) future.setException(new ProcessCanceledException());
+ return b;
+ }
+ @Override
+ public void run() {
try {
- ref.set(computable.compute());
+ future.set(computable.compute());
}
catch (Throwable e) {
- exRef.set(e);
+ future.setException(e);
}
}
- }, ModalityState.any());
+ });
+ }
+ try {
+ return (T)future.get();
+ }
+ catch (InterruptedException e) {
+ throw new ProcessCanceledException(e);
+ }
+ catch (ExecutionException e) {
+ throw (E) e.getCause();
}
- if (!exRef.isNull()) throw (E)exRef.get();
- return ref.get();
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java
index 62609d9ba5fc..0ae246d41715 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java
@@ -29,7 +29,7 @@ import com.intellij.openapi.updateSettings.impl.UpdateSettings;
import com.intellij.ui.DoubleClickListener;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.TableUtil;
-import com.intellij.util.net.HTTPProxySettingsDialog;
+import com.intellij.util.net.HttpConfigurable;
import com.intellij.util.ui.update.UiNotifyConnector;
import org.jetbrains.annotations.NotNull;
@@ -41,6 +41,7 @@ import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
import java.util.TreeSet;
/**
@@ -50,7 +51,7 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
public static final String MANAGE_REPOSITORIES = "Manage repositories...";
public static final String N_A = "N/A";
- private PluginManagerMain installed;
+ private final PluginManagerMain installed;
private final String myVendorFilter;
public AvailablePluginsManagerMain(PluginManagerMain installed, PluginManagerUISettings uiSettings, String vendorFilter) {
@@ -63,11 +64,11 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
manageRepositoriesBtn.setMnemonic('m');
manageRepositoriesBtn.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
if (ShowSettingsUtil.getInstance().editConfigurable(myActionsPanel, new PluginHostsConfigurable())) {
final ArrayList<String> pluginHosts = UpdateSettings.getInstance().myPluginHosts;
if (!pluginHosts.contains(((AvailablePluginsTableModel)pluginsModel).getRepository())) {
- ((AvailablePluginsTableModel)pluginsModel).setRepository(AvailablePluginsTableModel.ALL, myFilter.getFilter().toLowerCase());
+ ((AvailablePluginsTableModel)pluginsModel).setRepository(AvailablePluginsTableModel.ALL, myFilter.getFilter().toLowerCase(Locale.ENGLISH));
}
loadAvailablePlugins();
}
@@ -78,11 +79,9 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
final JButton httpProxySettingsButton = new JButton(IdeBundle.message("button.http.proxy.settings"));
httpProxySettingsButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- HTTPProxySettingsDialog settingsDialog = new HTTPProxySettingsDialog();
- settingsDialog.pack();
- settingsDialog.show();
- if (settingsDialog.isOK()) {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
+ if (HttpConfigurable.editConfigurable(getMainPanel())) {
loadAvailablePlugins();
}
}
@@ -114,7 +113,8 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
pluginTable.registerKeyboardAction(
new ActionListener() {
- public void actionPerformed(ActionEvent e) {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
installSelected(pluginTable);
}
},
@@ -235,7 +235,7 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
return new AnAction(availableCategory) {
@Override
public void actionPerformed(AnActionEvent e) {
- final String filter = myFilter.getFilter().toLowerCase();
+ final String filter = myFilter.getFilter().toLowerCase(Locale.ENGLISH);
((AvailablePluginsTableModel)pluginsModel).setCategory(availableCategory, filter);
}
};
@@ -277,7 +277,7 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
return new AnAction(host) {
@Override
public void actionPerformed(AnActionEvent e) {
- final String filter = myFilter.getFilter().toLowerCase();
+ final String filter = myFilter.getFilter().toLowerCase(Locale.ENGLISH);
((AvailablePluginsTableModel)pluginsModel).setRepository(host, filter);
TableUtil.ensureSelectionExists(getPluginTable());
}
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java
index a1ea238835cd..57329fb8fe9d 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java
@@ -15,6 +15,7 @@
*/
package com.intellij.ide.plugins;
+import com.intellij.diagnostic.PluginException;
import com.intellij.ide.ClassUtilCore;
import com.intellij.ide.IdeBundle;
import com.intellij.idea.IdeaApplication;
@@ -100,31 +101,44 @@ public class PluginManager extends PluginManagerCore {
public static void processException(Throwable t) {
if (!IdeaApplication.isLoaded()) {
- @SuppressWarnings("ThrowableResultOfMethodCallIgnored") StartupAbortedException se = findCause(t);
+ @SuppressWarnings("ThrowableResultOfMethodCallIgnored") StartupAbortedException se = findCause(t, StartupAbortedException.class);
if (se == null) se = new StartupAbortedException(t);
+ @SuppressWarnings("ThrowableResultOfMethodCallIgnored") PluginException pe = findCause(t, PluginException.class);
+ PluginId pluginId = pe != null ? pe.getPluginId() : null;
- if (se.logError()) {
+ if (Logger.isInitialized() && !(t instanceof ProcessCanceledException)) {
try {
- if (Logger.isInitialized() && !(t instanceof ProcessCanceledException)) {
- getLogger().error(t);
- }
+ getLogger().error(t);
}
catch (Throwable ignore) { }
+ }
+
+ if (pluginId != null && !CORE_PLUGIN_ID.equals(pluginId.getIdString())) {
+ disablePlugin(pluginId.getIdString());
+
+ StringWriter message = new StringWriter();
+ message.append("Plugin '").append(pluginId.getIdString()).append("' failed to initialize and will be disabled. ");
+ message.append(" Please restart ").append(ApplicationNamesInfo.getInstance().getFullProductName()).append('.');
+ message.append("\n\n");
+ pe.getCause().printStackTrace(new PrintWriter(message));
+ Main.showMessage("Plugin Error", message.toString(), false);
+ System.exit(Main.PLUGIN_ERROR);
+ }
+ else {
Main.showMessage("Start Failed", t);
+ System.exit(se.exitCode());
}
-
- System.exit(se.exitCode());
}
else if (!(t instanceof ProcessCanceledException)) {
getLogger().error(t);
}
}
- private static StartupAbortedException findCause(Throwable t) {
+ private static <T extends Throwable> T findCause(Throwable t, Class<T> clazz) {
while (t != null) {
- if (t instanceof StartupAbortedException) {
- return (StartupAbortedException)t;
+ if (clazz.isInstance(t)) {
+ return clazz.cast(t);
}
t = t.getCause();
}
@@ -229,18 +243,7 @@ public class PluginManager extends PluginManagerCore {
}
if (pluginId != null && !CORE_PLUGIN_ID.equals(pluginId.getIdString())) {
- getLogger().warn(t);
-
- disablePlugin(pluginId.getIdString());
-
- StringWriter message = new StringWriter();
- message.append("Plugin '").append(pluginId.getIdString()).append("' failed to initialize and will be disabled. ");
- message.append(" Please restart ").append(ApplicationNamesInfo.getInstance().getFullProductName()).append('.');
- message.append("\n\n");
- t.printStackTrace(new PrintWriter(message));
- Main.showMessage("Plugin Error", message.toString(), false);
-
- throw new StartupAbortedException(t).exitCode(Main.PLUGIN_ERROR).logError(false);
+ throw new StartupAbortedException(new PluginException(t, pluginId));
}
else {
throw new StartupAbortedException("Fatal error initializing '" + componentClassName + "'", t);
@@ -249,7 +252,6 @@ public class PluginManager extends PluginManagerCore {
private static class StartupAbortedException extends RuntimeException {
private int exitCode = Main.STARTUP_EXCEPTION;
- private boolean logError = true;
public StartupAbortedException(Throwable cause) {
super(cause);
@@ -267,14 +269,5 @@ public class PluginManager extends PluginManagerCore {
this.exitCode = exitCode;
return this;
}
-
- public boolean logError() {
- return logError;
- }
-
- public StartupAbortedException logError(boolean logError) {
- this.logError = logError;
- return this;
- }
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form b/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form
index 59197a00e70b..550e8e2482e1 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form
+++ b/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form
@@ -74,7 +74,7 @@
</component>
</children>
</grid>
- <grid id="d9fb" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="d9fb" layout-manager="GridLayoutManager" row-count="1" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -82,17 +82,6 @@
<properties/>
<border type="none"/>
<children>
- <component id="5ea1e" class="javax.swing.JComboBox" binding="myFontSizeCombo" custom-create="true">
- <constraints>
- <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false">
- <minimum-size width="140" height="-1"/>
- <preferred-size width="140" height="-1"/>
- </grid>
- </constraints>
- <properties>
- <editable value="true"/>
- </properties>
- </component>
<component id="76cd" class="javax.swing.JComboBox" binding="myFontCombo">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
@@ -107,15 +96,6 @@
<requestFocusEnabled value="true"/>
</properties>
</component>
- <component id="4eb1b" class="javax.swing.JLabel" binding="myFontSizeLabel">
- <constraints>
- <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <horizontalAlignment value="10"/>
- <text resource-bundle="messages/IdeBundle" key="label.font.size"/>
- </properties>
- </component>
<component id="23221" class="javax.swing.JLabel" binding="myFontNameLabel">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
@@ -127,11 +107,30 @@
</component>
<hspacer id="53ae4">
<constraints>
- <grid row="0" column="0" row-span="2" col-span="1" vsize-policy="1" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false">
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false">
<minimum-size width="20" height="-1"/>
</grid>
</constraints>
</hspacer>
+ <component id="4eb1b" class="javax.swing.JLabel" binding="myFontSizeLabel">
+ <constraints>
+ <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <horizontalAlignment value="10"/>
+ <text resource-bundle="messages/IdeBundle" key="label.font.size"/>
+ </properties>
+ </component>
+ <component id="5ea1e" class="javax.swing.JComboBox" binding="myFontSizeCombo" custom-create="true">
+ <constraints>
+ <grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="40" height="-1"/>
+ </grid>
+ </constraints>
+ <properties>
+ <editable value="true"/>
+ </properties>
+ </component>
</children>
</grid>
<grid id="ce348" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
diff --git a/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java b/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java
index bbd52139bd51..7ebf2a57a998 100644
--- a/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java
+++ b/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java
@@ -15,6 +15,7 @@
*/
package com.intellij.ide.util;
+import com.intellij.CommonBundle;
import com.intellij.ide.BrowserUtil;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
@@ -97,6 +98,7 @@ public class TipUIUtil {
String minor = ApplicationInfo.getInstance().getMinorVersion();
replaced = replaced.replace("&minorVersion;", minor);
replaced = replaced.replace("&majorMinorVersion;", major + ("0".equals(minor) ? "" : ("." + minor)));
+ replaced = replaced.replace("&settingsPath;", CommonBundle.settingsActionPath());
if (UIUtil.isUnderDarcula()) {
replaced = replaced.replace("css/tips.css", "css/tips_darcula.css");
}