diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/NextProjectWindow.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/NextProjectWindow.java new file mode 100644 index 000000000000..f6b7b5f2fbf3 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/NextProjectWindow.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2011 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.openapi.wm.impl; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.DumbAware; + +public class NextProjectWindow extends AnAction implements DumbAware { + + public void actionPerformed(AnActionEvent e) { + WindowDressing.getWindowActionGroup().activateNextWindow(e); + } + + @Override + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(WindowDressing.getWindowActionGroup().isEnabled()); + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/PreviousProjectWindow.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/PreviousProjectWindow.java new file mode 100644 index 000000000000..1776a5362334 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/PreviousProjectWindow.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2011 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.openapi.wm.impl; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.DumbAware; + +public class PreviousProjectWindow extends AnAction implements DumbAware { + + public void actionPerformed(AnActionEvent e) { + WindowDressing.getWindowActionGroup().activatePreviousWindow(e); + } + + @Override + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(WindowDressing.getWindowActionGroup().isEnabled()); + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ProjectWindowAction.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ProjectWindowAction.java new file mode 100644 index 000000000000..8a1d4a925317 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ProjectWindowAction.java @@ -0,0 +1,114 @@ +/* + * Copyright 2000-2011 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.openapi.wm.impl; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.actionSystem.ToggleAction; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.wm.WindowManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; + +/** + * This class is programmatically instantiated and registered when opening and closing projects + * and thus not registered in plugin.xml + */ +@SuppressWarnings({"ComponentNotRegistered"}) +public class ProjectWindowAction extends ToggleAction implements DumbAware { + + private ProjectWindowAction previous; + private ProjectWindowAction next; + + public ProjectWindowAction(@NotNull String projectName, ProjectWindowAction previous) { + super(projectName); + if (previous != null) { + this.previous = previous; + this.next = previous.next; + previous.next = this; + if (previous.previous == previous) { + previous.previous = this; + } + } else { + this.previous = this; + this.next = this; + } + } + + public void dispose() { + if (previous == this) { + assert next == this; + return; + } + if (next == this) { + assert false; + return; + } + previous.next = next; + next.previous = previous; + } + + public ProjectWindowAction getPrevious() { + return previous; + } + + public ProjectWindowAction getNext() { + return next; + } + + @Nullable + public static Frame findProjectFrame(@NotNull String projectName) { + final Project[] projects = ProjectManager.getInstance().getOpenProjects(); + for (Project project : projects) { + if (projectName.equals(project.getName())) { + final WindowManager windowManager = WindowManager.getInstance(); + return windowManager.getFrame(project); + } + } + return null; + } + + public boolean isSelected(AnActionEvent e) { + // show check mark for active and visible project frame + final Project project = e.getData(PlatformDataKeys.PROJECT); + if (project == null) { + return false; + } + final String text = getTemplatePresentation().getText(); + return text.equals(project.getName()); + } + + public void setSelected(@Nullable AnActionEvent e, boolean selected) { + if (!selected) { + return; + } + final Frame projectFrame = findProjectFrame(getTemplatePresentation().getText()); + if (projectFrame == null) { + return; + } + final int frameState = projectFrame.getExtendedState(); + if ((frameState & Frame.ICONIFIED) == Frame.ICONIFIED) { + // restore the frame if it is minimized + projectFrame.setExtendedState(frameState ^ Frame.ICONIFIED); + } + // bring the frame forward + projectFrame.toFront(); + } +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ProjectWindowActionGroup.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ProjectWindowActionGroup.java new file mode 100644 index 000000000000..5fd281d23298 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ProjectWindowActionGroup.java @@ -0,0 +1,98 @@ +/* + * Copyright 2000-2011 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.openapi.wm.impl; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +public class ProjectWindowActionGroup extends DefaultActionGroup { + + private ProjectWindowAction latest = null; + + public void addProject(@NotNull String name) { + final ProjectWindowAction windowAction = new ProjectWindowAction(name, latest); + add(windowAction); + latest = windowAction; + } + + public void removeProject(@NotNull String name) { + final ProjectWindowAction windowAction = findWindowAction(name); + if (windowAction == null) { + return; + } + if (latest == windowAction) { + final ProjectWindowAction previous = latest.getPrevious(); + if (previous != latest) { + latest = previous; + } else { + latest = null; + } + } + windowAction.dispose(); + remove(windowAction); + } + + public boolean isEnabled() { + return latest.getPrevious() != latest; + } + + @Override + public boolean isDumbAware() { + return true; + } + + public void activateNextWindow(AnActionEvent e) { + final Project project = e.getData(PlatformDataKeys.PROJECT); + if (project == null) { + return; + } + final ProjectWindowAction windowAction = findWindowAction(project.getName()); + final ProjectWindowAction next = windowAction.getNext(); + if (next != null) { + next.setSelected(e, true); + } + } + + public void activatePreviousWindow(AnActionEvent e) { + final Project project = e.getData(PlatformDataKeys.PROJECT); + if (project == null) { + return; + } + final ProjectWindowAction windowAction = findWindowAction(project.getName()); + final ProjectWindowAction previous = windowAction.getPrevious(); + if (previous != null) { + previous.setSelected(e, true); + } + } + + private ProjectWindowAction findWindowAction(String name) { + final AnAction[] children = getChildren(null); + for (AnAction child : children) { + if (!(child instanceof ProjectWindowAction)) { + continue; + } + final ProjectWindowAction windowAction = (ProjectWindowAction) child; + if (name.equals(windowAction.getTemplatePresentation().getText())) { + return windowAction; + } + } + return null; + } +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowDressing.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowDressing.java new file mode 100644 index 000000000000..977a447ea85e --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowDressing.java @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2011 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.openapi.wm.impl; + +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.components.AbstractProjectComponent; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +public class WindowDressing extends AbstractProjectComponent { + + public WindowDressing(@NotNull Project project) { + super(project); + } + + public void projectOpened() { + getWindowActionGroup().addProject(myProject.getName()); + } + + public void projectClosed() { + getWindowActionGroup().removeProject(myProject.getName()); + } + + public static ProjectWindowActionGroup getWindowActionGroup() { + return (ProjectWindowActionGroup)ActionManager.getInstance().getAction("OpenProjectWindows"); + } +} diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index e9c5f72d240e..e7b61fd46c6c 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -785,6 +785,11 @@ action.NextSplitter.text=_Goto Next Splitter action.NextSplitter.description=Goto next splitter window action.PrevSplitter.text=Goto Previous Splitter action.PrevSplitter.description=Goto previous splitter window +action.NextProjectWindow.text=Next Project Window +action.NextProjectWindow.description=Switch to the next project window +action.PreviousProjectWindow.text=Previous Project Window +action.PreviousProjectWindow.description=Switch to the previous project window +group.OpenProjectWindows.text=Open Project Windows group.HelpMenu.text=_Help action.HelpTopics.text=Help _Topics action.HelpTopics.description=Show help contents diff --git a/platform/platform-resources/src/componentSets/WindowManagement.xml b/platform/platform-resources/src/componentSets/WindowManagement.xml index 6a4b4a9b85e0..401a8a12772e 100644 --- a/platform/platform-resources/src/componentSets/WindowManagement.xml +++ b/platform/platform-resources/src/componentSets/WindowManagement.xml @@ -19,5 +19,9 @@ com.intellij.openapi.wm.impl.IdeFocusManagerImpl com.intellij.openapi.wm.impl.IdeFocusManagerHeadless + + com.intellij.openapi.wm.impl.WindowDressing + + \ No newline at end of file diff --git a/platform/platform-resources/src/idea/Keymap_Default.xml b/platform/platform-resources/src/idea/Keymap_Default.xml index 41215f4027df..e4ca0f809134 100644 --- a/platform/platform-resources/src/idea/Keymap_Default.xml +++ b/platform/platform-resources/src/idea/Keymap_Default.xml @@ -894,6 +894,12 @@ + + + + + + diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index 56f663d82b44..90fcd79d9f90 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -301,6 +301,11 @@ + + + + +