Initial structure view implementation for module (shows Libraries node, with libraries attached to this particular module).

This commit is contained in:
Maxim Shafirov
2009-11-24 22:11:08 +03:00
parent d0c7afba9e
commit 55e02a9b1c
5 changed files with 236 additions and 58 deletions
@@ -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() {
}
}
@@ -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;
}
};
}
}
@@ -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();
}
}
}
@@ -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);
}
}
}
}
@@ -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<AbstractTreeNode> getChildren() {
final List<AbstractTreeNode> children = new ArrayList<AbstractTreeNode>(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;
}
}