console view exposes actions

This commit is contained in:
Kirill Kalishev
2008-03-01 19:16:08 +03:00
parent 93d1a1ea14
commit df76fdd305
12 changed files with 246 additions and 62 deletions
@@ -34,6 +34,7 @@ import com.intellij.execution.ui.layout.RunnerLayoutUi;
import com.intellij.ide.CommonActionsManager;
import com.intellij.ide.actions.ContextHelpAction;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.ui.ComponentWithActions;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -290,7 +291,7 @@ public class DebuggerSessionTab implements LogConsoleManager, Disposable {
public void addLogConsole(final String name, final String path, final long skippedContent) {
final Ref<Content> content = new Ref<Content>();
final LogConsole log = new LogConsole(myProject, new File(path), skippedContent, name) {
final LogConsole log = new LogConsole(myProject, new File(path), skippedContent, name, false) {
public boolean isActive() {
final Content logContent = content.get();
return logContent != null && logContent.isSelected();
@@ -447,7 +448,7 @@ public class DebuggerSessionTab implements LogConsoleManager, Disposable {
private Content addLogComponent(final AdditionalTabComponent tabComponent) {
@NonNls final String id = "Log-" + tabComponent.getTabTitle();
final Content logContent = myUi.createContent(id, tabComponent.getComponent(), tabComponent.getTabTitle(),
final Content logContent = myUi.createContent(id, (ComponentWithActions)tabComponent, tabComponent.getTabTitle(),
IconLoader.getIcon("/fileTypes/text.png"), tabComponent.getPreferredFocusableComponent());
logContent.setDescription(tabComponent.getTooltip());
myAdditionalContent.put(tabComponent, logContent);
@@ -859,6 +859,8 @@ public final class ConsoleViewImpl extends JPanel implements ConsoleView, Observ
}
public JComponent getPreferredFocusableComponent() {
//ensure editor created
final JComponent component = getComponent();
return myEditor.getContentComponent();
}
@@ -17,6 +17,7 @@
package com.intellij.diagnostic.logging;
import com.intellij.openapi.ui.ComponentContainer;
import com.intellij.openapi.ui.ComponentWithActions;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -26,7 +27,7 @@ import java.awt.*;
* User: anna
* Date: 22-Mar-2006
*/
public abstract class AdditionalTabComponent extends JPanel implements ComponentContainer {
public abstract class AdditionalTabComponent extends JPanel implements ComponentContainer, ComponentWithActions {
protected AdditionalTabComponent(LayoutManager layout) {
super(layout);
}
@@ -4,6 +4,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComponentWithActions;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManagerListener;
import org.jetbrains.annotations.NotNull;
@@ -32,6 +33,9 @@ public interface RunnerLayoutUi {
@NotNull
Content createContent(@NotNull String contentId, @NotNull JComponent component, @NotNull String displayName, @Nullable Icon icon, @Nullable JComponent toFocus);
@NotNull
Content createContent(@NotNull String contentId, @NotNull ComponentWithActions contentWithActions, @NotNull String displayName, @Nullable Icon icon, @Nullable JComponent toFocus);
boolean removeContent(@Nullable Content content, boolean dispose);
@Nullable
@@ -56,13 +56,17 @@ public abstract class LogConsole extends AdditionalTabComponent implements Chang
private Project myProject;
private String myPath;
private boolean myWasInitialized;
private JPanel myTopComponent = new JPanel(new BorderLayout());
private ActionGroup myActions;
private boolean myBuildInActions;
public LogConsole(Project project, File file, long skippedContents, String title) {
public LogConsole(Project project, File file, long skippedContents, String title, final boolean buildInActions) {
super(new BorderLayout());
mySkippedContents = skippedContents;
myTitle = title;
myProject = project;
myPath = file.getAbsolutePath();
myBuildInActions = buildInActions;
myReaderThread = new ReaderThread(file);
TextConsoleBuilder builder = TextConsoleBuilderFactory.getInstance().createBuilder(project);
myConsole = builder.getConsole();
@@ -72,42 +76,10 @@ public abstract class LogConsole extends AdditionalTabComponent implements Chang
@SuppressWarnings({"NonStaticInitializer"})
private JComponent createToolbar(){
DefaultActionGroup group = new DefaultActionGroup();
final LogConsolePreferences registrar = getPreferences();
final ArrayList<LogFilter> filters = new ArrayList<LogFilter>();
filters.add(new LogFilter(DiagnosticBundle.message("log.console.filter.by.type", LogConsolePreferences.INFO), IconLoader.getIcon("/ant/filterInfo.png")){
public boolean isAcceptable(String line) {
return registrar.isApplicable(line, myPrevType);
}
});
filters.add(new LogFilter(DiagnosticBundle.message("log.console.filter.by.type", LogConsolePreferences.WARNING), IconLoader.getIcon("/ant/filterWarning.png")){
public boolean isAcceptable(String line) {
return registrar.isApplicable(line, myPrevType);
}
});
filters.add(new LogFilter(DiagnosticBundle.message("log.console.filter.by.type", LogConsolePreferences.ERROR), IconLoader.getIcon("/ant/filterError.png")){
public boolean isAcceptable(String line) {
return registrar.isApplicable(line, myPrevType);
}
});
filters.addAll(registrar.getRegisteredLogFilters());
for (final LogFilter filter : filters) {
group.add(new ToggleAction(filter.getName(), filter.getName(), filter.getIcon()){
public boolean isSelected(AnActionEvent e) {
return registrar.isFilterSelected(filter);
}
public void setSelected(AnActionEvent e, boolean state) {
registrar.setFilterSelected(filter, state);
}
});
}
final ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true);
JPanel panel = new JPanel(new BorderLayout());
panel.add(actionToolbar.getComponent(), BorderLayout.WEST);
myFilter.reset();
myFilter.setSelectedItem(registrar.CUSTOM_FILTER != null ? registrar.CUSTOM_FILTER : "");
panel.add(myFilter, BorderLayout.EAST);
new AnAction(){
{
registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, KeyEvent.SHIFT_DOWN_MASK)), LogConsole.this);
@@ -116,9 +88,67 @@ public abstract class LogConsole extends AdditionalTabComponent implements Chang
myFilter.requestFocusInWindow();
}
};
return panel;
if (myBuildInActions) {
final JComponent tbComp = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, getOrCreateActions(), true).getComponent();
myTopComponent.add(tbComp, BorderLayout.CENTER);
myTopComponent.add(myFilter, BorderLayout.EAST);
}
return myTopComponent;
}
public ActionGroup getOrCreateActions() {
if (myActions != null) return myActions;
final LogConsolePreferences prefs = getPreferences();
DefaultActionGroup group = new DefaultActionGroup();
final AnAction[] actions = myConsole.createUpDownStacktraceActions();
for (AnAction action : actions) {
group.add(action);
}
group.addSeparator();
final ArrayList<LogFilter> filters = new ArrayList<LogFilter>();
filters.add(new LogFilter(DiagnosticBundle.message("log.console.filter.by.type", LogConsolePreferences.INFO), IconLoader.getIcon("/ant/filterInfo.png")){
public boolean isAcceptable(String line) {
return prefs.isApplicable(line, myPrevType);
}
});
filters.add(new LogFilter(DiagnosticBundle.message("log.console.filter.by.type", LogConsolePreferences.WARNING), IconLoader.getIcon("/ant/filterWarning.png")){
public boolean isAcceptable(String line) {
return prefs.isApplicable(line, myPrevType);
}
});
filters.add(new LogFilter(DiagnosticBundle.message("log.console.filter.by.type", LogConsolePreferences.ERROR), IconLoader.getIcon("/ant/filterError.png")){
public boolean isAcceptable(String line) {
return prefs.isApplicable(line, myPrevType);
}
});
filters.addAll(prefs.getRegisteredLogFilters());
for (final LogFilter filter : filters) {
group.add(new ToggleAction(filter.getName(), filter.getName(), filter.getIcon()){
public boolean isSelected(AnActionEvent e) {
return prefs.isFilterSelected(filter);
}
public void setSelected(AnActionEvent e, boolean state) {
prefs.setFilterSelected(filter, state);
}
});
}
myActions = group;
return myActions;
}
public void onFilterStateChange(final LogFilter filter) {
filterConsoleOutput(new Condition<String>() {
public boolean value(final String line) {
@@ -138,12 +168,6 @@ public abstract class LogConsole extends AdditionalTabComponent implements Chang
public JComponent getComponent() {
if (!myWasInitialized) {
myWasInitialized = true;
final DefaultActionGroup group = new DefaultActionGroup();
final AnAction[] actions = myConsole.createUpDownStacktraceActions();
for (AnAction action : actions) {
group.add(action);
}
add(ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, false).getComponent(), BorderLayout.WEST);
add(myConsole.getComponent(), BorderLayout.CENTER);
add(createToolbar(), BorderLayout.NORTH);
}
@@ -383,8 +407,27 @@ public abstract class LogConsole extends AdditionalTabComponent implements Chang
}
}
public ActionGroup getToolbarActions() {
return getOrCreateActions();
}
public String getToolbarPlace() {
return ActionPlaces.UNKNOWN;
}
public JComponent getToolbarContextComponent() {
return myConsole.getComponent();
}
public JComponent getPreferredFocusableComponent() {
return myConsole.getPreferredFocusableComponent();
}
public JComponent getSearchComponent() {
return myFilter;
}
public boolean isContentBuiltIn() {
return myBuildInActions;
}
}
@@ -22,6 +22,7 @@ import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.execution.ui.layout.RunnerLayoutUi;
import com.intellij.ide.actions.ContextHelpAction;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.ui.ComponentWithActions;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
@@ -140,7 +141,7 @@ public class RunContentBuilder implements LogConsoleManager, Disposable {
}
public void addLogConsole(final String name, final String path, final long skippedContent) {
final LogConsole log = new LogConsole(myProject, new File(path), skippedContent, name){
final LogConsole log = new LogConsole(myProject, new File(path), skippedContent, name, false){
public boolean isActive() {
final Content content = myUi.findContent(path);
return content != null && content.isSelected();
@@ -210,7 +211,7 @@ public class RunContentBuilder implements LogConsoleManager, Disposable {
}
public void addAdditionalTabComponent(final AdditionalTabComponent tabComponent, final String id) {
final Content content = myUi.createContent(id, tabComponent.getComponent(), tabComponent.getTabTitle(),
final Content content = myUi.createContent(id, (ComponentWithActions)tabComponent, tabComponent.getTabTitle(),
IconLoader.getIcon("/debugger/console.png"), tabComponent.getPreferredFocusableComponent());
@@ -1,7 +1,7 @@
package com.intellij.execution.ui.layout.impl;
import com.intellij.execution.ui.layout.actions.RestoreViewAction;
import com.intellij.execution.ui.layout.RunnerLayoutUi;
import com.intellij.execution.ui.layout.actions.RestoreViewAction;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.Project;
@@ -224,19 +224,26 @@ public class RunnerContentUi
TabInfo tab = new TabInfo(grid).setObject(getStateFor(content).getTab()).setText("Tab");
Wrapper leftWrapper = new Wrapper();
myCommonActionsPlaceholder.put(grid, leftWrapper);
Wrapper left = new Wrapper();
myCommonActionsPlaceholder.put(grid, left);
Wrapper rightWrapper = new Wrapper();
myMinimizedButtonsPlaceholder.put(grid, rightWrapper);
NonOpaquePanel sideComponent = new NonOpaquePanel(new CommonToolbarLayout(leftWrapper, rightWrapper));
Wrapper minimizedToolbar = new Wrapper();
myMinimizedButtonsPlaceholder.put(grid, minimizedToolbar);
final Wrapper searchComponent = new Wrapper();
if (content.getSearchComponent() != null) {
searchComponent.setContent(content.getSearchComponent());
}
TwoSideComponent right = new TwoSideComponent(searchComponent, minimizedToolbar);
NonOpaquePanel sideComponent = new TwoSideComponent(left, right);
tab.setSideComponent(sideComponent);
sideComponent.add(leftWrapper);
sideComponent.add(rightWrapper);
tab.setTabLabelActions((ActionGroup)myActionManager.getAction(VIEW_TOOLBAR), TAB_TOOLBAR_PLACE);
myTabs.addTab(tab);
@@ -757,6 +764,14 @@ public class RunnerContentUi
});
}
private class TwoSideComponent extends NonOpaquePanel {
private TwoSideComponent(JComponent left, JComponent right) {
setLayout(new CommonToolbarLayout(left, right));
add(left);
add(right);
}
}
private static class CommonToolbarLayout extends AbstractLayoutManager {
private final JComponent myLeft;
private final JComponent myRight;
@@ -805,6 +820,23 @@ public class RunnerContentUi
myRight.setBounds((int)myLeft.getBounds().getMaxX(), 0, parent.getWidth() - myLeft.getWidth(), parent.getHeight());
}
toMakeVerticallyInCenter(myLeft, parent);
toMakeVerticallyInCenter(myRight, parent);
}
private void toMakeVerticallyInCenter(JComponent comp, Container parent) {
final Rectangle compBounds = comp.getBounds();
int compHeight = comp.getPreferredSize().height;
final int parentHeight = parent.getHeight();
if (compHeight > parentHeight) {
compHeight = parentHeight;
}
int y = (int)Math.floor(parentHeight / 2.0 - compHeight / 2.0);
comp.setBounds(compBounds.x, y, compBounds.width, compHeight);
}
}
@@ -2,6 +2,7 @@ package com.intellij.execution.ui.layout.impl;
import com.intellij.execution.ui.layout.RunnerLayoutUi;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.ui.ComponentWithActions;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
@@ -84,16 +85,28 @@ public class RunnerLayoutUiImpl implements Disposable, RunnerLayoutUi {
@NotNull
public Content createContent(@NotNull String id, @NotNull JComponent component, @NotNull String displayName, @Nullable Icon icon, @Nullable JComponent focusable) {
final Content content = getContentFactory().createContent(component, displayName, false);
content.putUserData(CONTENT_TYPE, id);
content.putUserData(View.ID, id);
content.setIcon(icon);
if (focusable != null) {
content.setPreferredFocusableComponent(focusable);
}
return content;
return createContent(id, new ComponentWithActions.Impl(component), displayName, icon, focusable);
}
@NotNull
public Content createContent(@NotNull final String contentId, @NotNull final ComponentWithActions withActions, @NotNull final String displayName,
@Nullable final Icon icon,
@Nullable final JComponent toFocus) {
final Content content = getContentFactory().createContent(withActions.getComponent(), displayName, false);
content.putUserData(CONTENT_TYPE, contentId);
content.putUserData(View.ID, contentId);
content.setIcon(icon);
if (toFocus != null) {
content.setPreferredFocusableComponent(toFocus);
}
if (!withActions.isContentBuiltIn()) {
content.setSearchComponent(withActions.getSearchComponent());
content.setActions(withActions.getToolbarActions(), withActions.getToolbarPlace(), withActions.getToolbarContextComponent());
}
return content;
}
@NotNull
public JComponent getComponent() {
@@ -0,0 +1,74 @@
package com.intellij.openapi.ui;
import com.intellij.openapi.actionSystem.ActionGroup;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public interface ComponentWithActions {
@Nullable
ActionGroup getToolbarActions();
@Nullable
JComponent getSearchComponent();
@Nullable
String getToolbarPlace();
@Nullable
JComponent getToolbarContextComponent();
@NotNull
JComponent getComponent();
boolean isContentBuiltIn();
class Impl implements ComponentWithActions {
private ActionGroup myToolbar;
private String myToolbarPlace;
private JComponent myToolbarContext;
private JComponent mySearchComponent;
private JComponent myComponent;
public Impl(final ActionGroup toolbar, final String toolbarPlace, final JComponent toolbarContext,
final JComponent searchComponent,
final JComponent component) {
myToolbar = toolbar;
myToolbarPlace = toolbarPlace;
myToolbarContext = toolbarContext;
mySearchComponent = searchComponent;
myComponent = component;
}
public boolean isContentBuiltIn() {
return false;
}
public Impl(final JComponent component) {
this(null, null, null, null, component);
}
public ActionGroup getToolbarActions() {
return myToolbar;
}
public JComponent getSearchComponent() {
return mySearchComponent;
}
public String getToolbarPlace() {
return myToolbarPlace;
}
public JComponent getToolbarContextComponent() {
return myToolbarContext;
}
@NotNull
public JComponent getComponent() {
return myComponent;
}
}
}
@@ -87,8 +87,10 @@ public interface Content extends UserDataHolder, ComponentContainer {
void setCloseable(boolean closeable);
void setActions(ActionGroup actions, String place, @Nullable JComponent contextComponent);
void setSearchComponent(@Nullable JComponent comp);
ActionGroup getActions();
@Nullable JComponent getSearchComponent();
String getPlace();
JComponent getActionsContextComponent();
@@ -268,6 +268,8 @@ public class JBTabs extends JComponent implements PropertyChangeListener, TimerL
private JComponent getToFocus() {
final TabInfo info = getSelectedInfo();
if (info == null) return null;
JComponent toFocus = null;
if (isRequestFocusOnLastFocusedComponent() && info.getLastFocusOwner() != null && !isMyChildIsFocusedNow()) {
@@ -41,6 +41,7 @@ public class ContentImpl extends UserDataHolderBase implements Content {
private boolean myAlerting = false;
private JComponent myActionsContextComponent;
private JComponent mySearchComponent;
public ContentImpl(JComponent component, String displayName, boolean isPinnable) {
myComponent = component;
@@ -229,4 +230,12 @@ public class ContentImpl extends UserDataHolderBase implements Content {
public void fireAlert() {
myChangeSupport.firePropertyChange(PROP_ALERT, null, true);
}
public void setSearchComponent(@Nullable final JComponent comp) {
mySearchComponent = comp;
}
public JComponent getSearchComponent() {
return mySearchComponent;
}
}