提交 ec89a599 编写于 作者: S Sandeep Somavarapu

#23912 Adopt actions

上级 735c6d3b
......@@ -188,10 +188,15 @@
}
.search-viewlet .linematch {
overflow: hidden;
text-overflow: ellipsis;
position: relative;
line-height: 22px;
display: flex;
}
.search-viewlet .linematch > .match {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
}
.search-viewlet .linematch.changedOrRemoved {
......@@ -224,6 +229,35 @@
background: url("action-query-clear.svg") center center no-repeat;
}
.search-viewlet .monaco-tree .monaco-tree-row .monaco-action-bar {
line-height: 1em;
display: none;
padding: 0 0.8em 0 0.4em;
}
.search-viewlet .monaco-tree .monaco-tree-row .monaco-action-bar .action-item {
margin: 0;
}
.search-viewlet .monaco-tree .monaco-tree-row.focused .monaco-action-bar {
width: 0; /* in order to support a11y with keyboard, we use width: 0 to hide the actions, which still allows to "Tab" into the actions */
display: block;
}
.search-viewlet .monaco-tree .monaco-tree-row:hover:not(.highlighted) .monaco-action-bar,
.search-viewlet .monaco-tree .monaco-tree-row.focused .monaco-action-bar {
width: inherit;
display: block;
}
.search-viewlet .monaco-tree .monaco-tree-row .monaco-action-bar .action-label {
margin-right: 0.2em;
margin-top: 4px;
background-repeat: no-repeat;
width: 16px;
height: 16px;
}
.search-viewlet .action-remove {
background: url("action-remove.svg") center center no-repeat;
}
......
......@@ -12,11 +12,11 @@ import * as DOM from 'vs/base/browser/dom';
import { Disposable } from 'vs/base/common/lifecycle';
import { TPromise } from 'vs/base/common/winjs.base';
import { IAction, IActionRunner } from 'vs/base/common/actions';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge';
import { FileLabel } from 'vs/workbench/browser/labels';
import { ITree, IDataSource, ISorter, IAccessibilityProvider, IFilter, IRenderer } from 'vs/base/parts/tree/browser/tree';
import { ClickBehavior, DefaultController } from 'vs/base/parts/tree/browser/treeDefaults';
import { ContributableActionProvider } from 'vs/workbench/browser/actionBarRegistry';
import { Match, SearchResult, FileMatch, FileMatchOrMatch, SearchModel } from 'vs/workbench/parts/search/common/searchModel';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { Range } from 'vs/editor/common/core/range';
......@@ -93,40 +93,10 @@ export class SearchSorter implements ISorter {
}
}
class SearchActionProvider extends ContributableActionProvider {
constructor(private viewlet: SearchViewlet, @IInstantiationService private instantiationService: IInstantiationService) {
super();
}
public hasActions(tree: ITree, element: any): boolean {
let input = <SearchResult>tree.getInput();
return element instanceof FileMatch || (element instanceof Match && input.searchModel.isReplaceActive()) || super.hasActions(tree, element);
}
public getActions(tree: ITree, element: any): TPromise<IAction[]> {
return super.getActions(tree, element).then(actions => {
let input = <SearchResult>tree.getInput();
if (element instanceof FileMatch) {
actions.unshift(new RemoveAction(tree, element));
if (input.searchModel.isReplaceActive() && element.count() > 0) {
actions.unshift(this.instantiationService.createInstance(ReplaceAllAction, tree, element, this.viewlet));
}
}
if (element instanceof Match) {
if (input.searchModel.isReplaceActive()) {
actions.unshift(this.instantiationService.createInstance(ReplaceAction, tree, element, this.viewlet), new RemoveAction(tree, element));
}
}
return actions;
});
}
}
interface IFileMatchTemplate {
label: FileLabel;
badge: CountBadge;
actions: ActionBar;
}
interface IMatchTemplate {
......@@ -135,6 +105,7 @@ interface IMatchTemplate {
match: HTMLElement;
replace?: HTMLElement;
after: HTMLElement;
actions: ActionBar;
}
export class SearchRenderer extends Disposable implements IRenderer {
......@@ -142,7 +113,7 @@ export class SearchRenderer extends Disposable implements IRenderer {
private static FILE_MATCH_TEMPLATE_ID = 'fileMatch';
private static MATCH_TEMPLATE_ID = 'match';
constructor(actionRunner: IActionRunner, viewlet: SearchViewlet, @IWorkspaceContextService private contextService: IWorkspaceContextService,
constructor(actionRunner: IActionRunner, private viewlet: SearchViewlet, @IWorkspaceContextService private contextService: IWorkspaceContextService,
@IInstantiationService private instantiationService: IInstantiationService) {
super();
}
......@@ -174,7 +145,7 @@ export class SearchRenderer extends Disposable implements IRenderer {
public renderElement(tree: ITree, element: any, templateId: string, templateData: any): void {
if (SearchRenderer.FILE_MATCH_TEMPLATE_ID === templateId) {
this.renderFileMatch(<FileMatch>element, <IFileMatchTemplate>templateData);
this.renderFileMatch(tree, <FileMatch>element, <IFileMatchTemplate>templateData);
} else if (SearchRenderer.MATCH_TEMPLATE_ID === templateId) {
this.renderMatch(tree, <Match>element, <IMatchTemplate>templateData);
}
......@@ -185,33 +156,45 @@ export class SearchRenderer extends Disposable implements IRenderer {
let fileMatchElement = DOM.append(container, DOM.$('.filematch'));
const label = this.instantiationService.createInstance(FileLabel, fileMatchElement, void 0);
const badge = new CountBadge(DOM.append(fileMatchElement, DOM.$('.badge')));
return { label, badge };
const actions = new ActionBar(fileMatchElement, { animated: false });
return { label, badge, actions };
}
private renderMatchTemplate(tree: ITree, templateId: string, container: HTMLElement): IMatchTemplate {
DOM.addClass(container, 'linematch');
const parent = DOM.append(container, DOM.$('a.plain'));
const parent = DOM.append(container, DOM.$('a.plain.match'));
const before = DOM.append(parent, DOM.$('span'));
const match = DOM.append(parent, DOM.$('span.findInFileMatch'));
const replace = DOM.append(parent, DOM.$('span.replaceMatch'));
const after = DOM.append(parent, DOM.$('span'));
const actions = new ActionBar(container, { animated: false });
return {
parent,
before,
match,
replace,
after
after,
actions
};
}
private renderFileMatch(fileMatch: FileMatch, templateData: IFileMatchTemplate): void {
private renderFileMatch(tree: ITree, fileMatch: FileMatch, templateData: IFileMatchTemplate): void {
templateData.label.setFile(fileMatch.resource());
let count = fileMatch.count();
templateData.badge.setCount(count);
templateData.badge.setTitleFormat(count > 1 ? nls.localize('searchMatches', "{0} matches found", count) : nls.localize('searchMatch', "{0} match found", count));
let input = <SearchResult>tree.getInput();
templateData.actions.clear();
const actions: IAction[] = [];
if (input.searchModel.isReplaceActive() && count > 0) {
actions.push(this.instantiationService.createInstance(ReplaceAllAction, tree, fileMatch, this.viewlet));
}
actions.push(new RemoveAction(tree, fileMatch));
templateData.actions.push(actions, { icon: true, label: false });
}
private renderMatch(tree: ITree, match: Match, templateData: IMatchTemplate): void {
......@@ -225,6 +208,11 @@ export class SearchRenderer extends Disposable implements IRenderer {
templateData.replace.textContent = replace ? strings.escape(match.replaceString) : '';
templateData.after.textContent = strings.escape(preview.after);
templateData.parent.title = (preview.before + (templateData.replace ? match.replaceString : preview.inside) + preview.after).trim().substr(0, 999);
templateData.actions.clear();
if (searchModel.isReplaceActive()) {
templateData.actions.push([this.instantiationService.createInstance(ReplaceAction, tree, match, this.viewlet), new RemoveAction(tree, match)], { icon: true, label: false });
}
}
public disposeTemplate(tree: ITree, templateId: string, templateData: any): void {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册