diff --git a/platform/lang-impl/src/com/intellij/ide/impl/ModuleStructureComponent.java b/platform/lang-impl/src/com/intellij/ide/impl/ModuleStructureComponent.java new file mode 100644 index 000000000000..575e39e8e5ae --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/impl/ModuleStructureComponent.java @@ -0,0 +1,41 @@ +/* + * 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. + */ + +/* + * @author max + */ +package com.intellij.ide.impl; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.ui.SimpleToolWindowPanel; +import com.intellij.openapi.util.Disposer; + +public class ModuleStructureComponent extends SimpleToolWindowPanel implements Disposable { + public ModuleStructureComponent(Module module) { + super(true, true); + + final ModuleStructurePane structurePane = new ModuleStructurePane(module); + Disposer.register(this, structurePane); + + setContent(structurePane.createComponent()); + } + + + public void dispose() { + + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/impl/ModuleStructurePane.java b/platform/lang-impl/src/com/intellij/ide/impl/ModuleStructurePane.java new file mode 100644 index 000000000000..3bc7cb4c7127 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/impl/ModuleStructurePane.java @@ -0,0 +1,52 @@ +/* + * 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. + */ + +/* + * @author max + */ +package com.intellij.ide.impl; + +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.projectView.impl.ProjectAbstractTreeStructureBase; +import com.intellij.ide.projectView.impl.ProjectTreeStructure; +import com.intellij.ide.projectView.impl.ProjectViewPane; +import com.intellij.ide.projectView.impl.nodes.StructureViewModuleNode; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; + +public class ModuleStructurePane extends ProjectViewPane { + private Module myModule; + + public ModuleStructurePane(Module module) { + super(module.getProject()); + myModule = module; + } + + @Override + protected ProjectAbstractTreeStructureBase createStructure() { + return new ProjectTreeStructure(myProject, ID){ + protected AbstractTreeNode createRoot(final Project project, ViewSettings settings) { + return new StructureViewModuleNode(project, myModule, settings); + } + + @Override + public boolean isToBuildChildrenInBackground(Object element) { + return false; + } + }; + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/impl/StructureViewWrapperImpl.java b/platform/lang-impl/src/com/intellij/ide/impl/StructureViewWrapperImpl.java index 82caf43ef455..87545027c1ad 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/StructureViewWrapperImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/StructureViewWrapperImpl.java @@ -16,14 +16,16 @@ package com.intellij.ide.impl; +import com.intellij.ide.DataManager; import com.intellij.ide.IdeBundle; import com.intellij.ide.structureView.StructureView; import com.intellij.ide.structureView.StructureViewBuilder; import com.intellij.ide.structureView.StructureViewWrapper; import com.intellij.openapi.Disposable; -import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ModalityState; -import com.intellij.openapi.fileEditor.*; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; @@ -32,7 +34,6 @@ import com.intellij.openapi.wm.ToolWindowId; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; import com.intellij.psi.PsiDocumentManager; -import com.intellij.util.Alarm; import com.intellij.util.IJSwingUtilities; import com.intellij.util.ui.UIUtil; @@ -46,14 +47,15 @@ import java.awt.event.HierarchyListener; */ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposable { private final Project myProject; + private FileEditor myFileEditor; + private Module myModule; private StructureView myStructureView; + private ModuleStructureComponent myModuleStructureComponent; private final JPanel myPanel; - private final Alarm myAlarm; - // ------------------------------------------------------------------------- // Constructor // ------------------------------------------------------------------------- @@ -63,7 +65,15 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl myPanel = new JPanel(new BorderLayout()); myPanel.setBackground(UIUtil.getTreeTextBackground()); - myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); + ActionManager.getInstance().addTimerListener(500, new TimerListener() { + public ModalityState getModalityState() { + return ModalityState.NON_MODAL; + } + + public void run() { + checkUpdate(); + } + }); getComponent().addHierarchyListener(new HierarchyListener() { public void hierarchyChanged(HierarchyEvent e) { @@ -72,39 +82,33 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl } } }); - - FileEditorManagerListener editorManagerListener = new FileEditorManagerAdapter() { - private FileEditorManagerEvent myLastEvent; - - public void selectionChanged(final FileEditorManagerEvent event) { - myLastEvent = event; - myAlarm.cancelAllRequests(); - myAlarm.addRequest(new Runnable() { - public void run() { - ApplicationManager.getApplication().invokeLater(new Runnable() { - public void run() { - if (myLastEvent == null) { - return; - } - try { - if (myProject.isDisposed()) { - return; // project may have been closed - } - PsiDocumentManager.getInstance(myProject).commitAllDocuments(); - setFileEditor(myLastEvent.getNewEditor()); - } - finally { - myLastEvent = null; - } - } - }, ModalityState.NON_MODAL); - } - }, 400); - } - }; - FileEditorManager.getInstance(project).addFileEditorManagerListener(editorManagerListener,this); } + private void checkUpdate() { + if (myProject.isDisposed()) return; + + Window mywindow = SwingUtilities.windowForComponent(myPanel); + if (mywindow != null && !mywindow.isActive()) return; + + final KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); + final Window focusWindow = focusManager.getFocusedWindow(); + + if (focusWindow == mywindow) { + final Component owner = focusManager.getFocusOwner(); + if (owner == null || SwingUtilities.isDescendingFrom(owner, myPanel)) return; + + final DataContext dataContext = DataManager.getInstance().getDataContext(owner); + final FileEditor fileEditor = PlatformDataKeys.FILE_EDITOR.getData(dataContext); + if (fileEditor != null) { + setFileEditor(fileEditor); + } + else { + setModule(LangDataKeys.MODULE_CONTEXT.getData(dataContext)); + } + } + } + + // ------------------------------------------------------------------------- // StructureView interface implementation // ------------------------------------------------------------------------- @@ -120,48 +124,77 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl public boolean selectCurrentElement(FileEditor fileEditor, boolean requestFocus) { if (myStructureView != null) { - if (!Comparing.equal(myStructureView.getFileEditor(), fileEditor)){ + if (!Comparing.equal(myStructureView.getFileEditor(), fileEditor)) { setFileEditor(fileEditor); rebuild(); } return myStructureView.navigateToSelectedElement(requestFocus); - } else { + } + else { return false; } } - // ------------------------------------------------------------------------- - // Helper methods - // ------------------------------------------------------------------------- - - - public void setFileEditor(FileEditor fileEditor) { - final boolean fileChanged = myFileEditor != null ? !myFileEditor.equals(fileEditor) : fileEditor != null; - if (fileChanged) { - myFileEditor = fileEditor; - } - if (fileChanged || - isStructureViewShowing() && myPanel.getComponentCount() == 0 && myFileEditor != null) { + private void setModule(Module module) { + if (module != myModule) { + myModule = module; rebuild(); } } + public void setFileEditor(FileEditor fileEditor) { + if (myModule != null) { + myModule = null; + rebuild(); + } + else { + if (!Comparing.equal(myFileEditor, fileEditor)) { + myFileEditor = fileEditor; + rebuild(); + return; + } + + if (isStructureViewShowing() && myPanel.getComponentCount() == 0 && myFileEditor != null) { + rebuild(); + } + } + + } + public void rebuild() { PsiDocumentManager.getInstance(myProject).commitAllDocuments(); - boolean hadFocus = myStructureView != null && IJSwingUtilities.hasFocus2(myStructureView.getComponent()); + boolean hadFocus = myStructureView != null && IJSwingUtilities.hasFocus2(myStructureView.getComponent()) || + myModuleStructureComponent != null && IJSwingUtilities.hasFocus2(myModuleStructureComponent); + if (myStructureView != null) { myStructureView.storeState(); Disposer.dispose(myStructureView); myStructureView = null; } + + if (myModuleStructureComponent != null) { + Disposer.dispose(myModuleStructureComponent); + myModuleStructureComponent = null; + } + myPanel.removeAll(); if (!isStructureViewShowing()) { return; } - if (myFileEditor!=null && myFileEditor.isValid()) { + if (myModule != null) { + myModuleStructureComponent = new ModuleStructureComponent(myModule); + myPanel.add(myModuleStructureComponent, BorderLayout.CENTER); + if (hadFocus) { + JComponent focusedComponent = IdeFocusTraversalPolicy.getPreferredFocusedComponent(myModuleStructureComponent); + if (focusedComponent != null) { + focusedComponent.requestFocus(); + } + } + } + else if (myFileEditor != null && myFileEditor.isValid()) { final StructureViewBuilder structureViewBuilder = myFileEditor.getStructureViewBuilder(); if (structureViewBuilder != null) { myStructureView = structureViewBuilder.createStructureView(myFileEditor, myProject); @@ -176,7 +209,8 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl myStructureView.centerSelectedRow(); } } - if (myStructureView == null) { + + if (myModuleStructureComponent == null && myStructureView == null) { myPanel.add(new JLabel(IdeBundle.message("message.nothing.to.show.in.structure.view"), SwingConstants.CENTER), BorderLayout.CENTER); } @@ -187,8 +221,8 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl protected boolean isStructureViewShowing() { ToolWindowManager windowManager = ToolWindowManager.getInstance(myProject); - ToolWindow toolWindow=windowManager.getToolWindow(ToolWindowId.STRUCTURE_VIEW); + ToolWindow toolWindow = windowManager.getToolWindow(ToolWindowId.STRUCTURE_VIEW); // it means that window is registered return toolWindow != null && toolWindow.isVisible(); } -} \ No newline at end of file +} diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewPane.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewPane.java index cdfba876a1a1..e8a70cfe2342 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewPane.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewPane.java @@ -38,7 +38,7 @@ import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; -public final class ProjectViewPane extends AbstractProjectViewPSIPane { +public class ProjectViewPane extends AbstractProjectViewPSIPane { @NonNls public static final String ID = "ProjectPane"; private static final Icon ICON = IconLoader.getIcon("/general/projectTab.png"); @@ -128,4 +128,4 @@ public final class ProjectViewPane extends AbstractProjectViewPSIPane { return super.addSubtreeToUpdateByElement(element); } } -} \ No newline at end of file +} diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/StructureViewModuleNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/StructureViewModuleNode.java new file mode 100644 index 000000000000..397064957117 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/StructureViewModuleNode.java @@ -0,0 +1,51 @@ +/* + * 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.projectView.impl.nodes; + +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class StructureViewModuleNode extends AbstractModuleNode { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode"); + + public StructureViewModuleNode(Project project, Module value, ViewSettings viewSettings) { + super(project, value, viewSettings); + } + + @NotNull + public Collection getChildren() { + final List children = new ArrayList(2); + children.add(new LibraryGroupNode(getProject(), new LibraryGroupElement(getValue()), getSettings())); + return children; + } + + public int getWeight() { + return 10; + } + + public int getTypeSortWeight(final boolean sortByType) { + return 2; + } +}