Skip to content

Commit

Permalink
GH-7521: Enabled Select All in the Output.
Browse files Browse the repository at this point in the history
Closes #7521.

Signed-off-by: Akos Kitta <kittaakos@typefox.io>
  • Loading branch information
Akos Kitta authored and kittaakos committed Apr 8, 2020
1 parent 260ab0b commit b8c4269
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 7 deletions.
49 changes: 47 additions & 2 deletions packages/output/src/browser/output-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,56 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { injectable } from 'inversify';
import { injectable, inject } from 'inversify';
import { AbstractViewContribution } from '@theia/core/lib/browser/shell/view-contribution';
import { Widget } from '@theia/core/lib/browser';
import { Widget, KeybindingRegistry, KeybindingContext, ApplicationShell } from '@theia/core/lib/browser';
import { OUTPUT_WIDGET_KIND, OutputWidget } from './output-widget';
import { Command, CommandRegistry } from '@theia/core/lib/common';

export namespace OutputCommands {

const OUTPUT_CATEGORY = 'Output';

export const CLEAR_OUTPUT_TOOLBAR: Command = {
id: 'output:clear',
category: OUTPUT_CATEGORY,
label: 'Clear Output',
iconClass: 'clear-all'
};

export const SELECT_ALL: Command = {
id: 'output:selectAll',
category: OUTPUT_CATEGORY,
label: 'Select All'
};

}

/**
* Enabled when the `Output` widget is the `activeWidget` in the shell.
*/
@injectable()
export class OutputWidgetIsActiveContext implements KeybindingContext {

static readonly ID = 'output:isActive';

@inject(ApplicationShell)
protected readonly shell: ApplicationShell;

readonly id = OutputWidgetIsActiveContext.ID;

isEnabled(): boolean {
return this.shell.activeWidget instanceof OutputWidget;
}

}

@injectable()
export class OutputContribution extends AbstractViewContribution<OutputWidget> {

@inject(OutputWidgetIsActiveContext)
protected readonly outputIsActiveContext: OutputWidgetIsActiveContext;

constructor() {
super({
widgetId: OUTPUT_WIDGET_KIND,
Expand All @@ -52,6 +83,20 @@ export class OutputContribution extends AbstractViewContribution<OutputWidget> {
isVisible: widget => this.withWidget(widget, () => true),
execute: widget => this.withWidget(widget, outputWidget => this.clear(outputWidget))
});
commands.registerCommand(OutputCommands.SELECT_ALL, {
isEnabled: () => this.outputIsActiveContext.isEnabled(),
isVisible: () => this.outputIsActiveContext.isEnabled(),
execute: widget => this.withWidget(widget, outputWidget => outputWidget.selectAll())
});
}

registerKeybindings(registry: KeybindingRegistry): void {
super.registerKeybindings(registry);
registry.registerKeybindings({
command: OutputCommands.SELECT_ALL.id,
keybinding: 'CtrlCmd+A',
context: OutputWidgetIsActiveContext.ID
});
}

protected async clear(widget: OutputWidget): Promise<void> {
Expand Down
10 changes: 6 additions & 4 deletions packages/output/src/browser/output-frontend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { ContainerModule, interfaces } from 'inversify';
import { ContainerModule } from 'inversify';
import { OutputWidget, OUTPUT_WIDGET_KIND } from './output-widget';
import { WidgetFactory, bindViewContribution } from '@theia/core/lib/browser';
import { OutputContribution } from './output-contribution';
import { WidgetFactory, bindViewContribution, KeybindingContext } from '@theia/core/lib/browser';
import { OutputContribution, OutputWidgetIsActiveContext } from './output-contribution';
import { OutputToolbarContribution } from './output-toolbar-contribution';
import { OutputChannelManager } from '../common/output-channel';
import { bindOutputPreferences } from '../common/output-preferences';
import { TabBarToolbarContribution } from '@theia/core/lib/browser/shell/tab-bar-toolbar';

export default new ContainerModule((bind: interfaces.Bind, unbind: interfaces.Unbind, isBound: interfaces.IsBound, rebind: interfaces.Rebind) => {
export default new ContainerModule((bind, unbind, isBound, rebind) => {
bindOutputPreferences(bind);
bind(OutputWidget).toSelf();
bind(OutputChannelManager).toSelf().inSingletonScope();
Expand All @@ -34,6 +34,8 @@ export default new ContainerModule((bind: interfaces.Bind, unbind: interfaces.Un
}));

bindViewContribution(bind, OutputContribution);
bind(OutputWidgetIsActiveContext).toSelf().inSingletonScope();
bind(KeybindingContext).toService(OutputWidgetIsActiveContext);
bind(OutputToolbarContribution).toSelf().inSingletonScope();
bind(TabBarToolbarContribution).toService(OutputToolbarContribution);
});
21 changes: 20 additions & 1 deletion packages/output/src/browser/output-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,31 @@ export class OutputWidget extends ReactWidget {
</React.Fragment>;
}

public clear(): void {
clear(): void {
if (this.outputChannelManager.selectedChannel) {
this.outputChannelManager.selectedChannel.clear();
}
}

selectAll(): void {
if (this.outputChannelManager.selectedChannel) {
const element = document.getElementById(OutputWidget.IDs.CONTENTS);
if (element) {
const selectElementContent = (htmlElement: HTMLElement) => {
const selection = window.getSelection();
const range = document.createRange();
if (selection && range) {
range.selectNodeContents(htmlElement);
selection.removeAllRanges();
selection.addRange(range);
}
};
element.focus();
selectElementContent(element);
}
}
}

protected renderChannelContents(): React.ReactNode {
return <div id={OutputWidget.IDs.CONTENTS}>{this.renderLines()}</div>;
}
Expand Down

0 comments on commit b8c4269

Please sign in to comment.