diff options
Diffstat (limited to 'platform/platform-impl/src/com/intellij/ide')
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> </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"); } |