提交 1775a08e 编写于 作者: J Joao Moreno

git: status bar

上级 01588751
......@@ -14,6 +14,7 @@ import { AutoFetcher } from './autofetch';
import * as path from 'path';
import * as nls from 'vscode-nls';
import * as fs from 'fs';
import { StatusBarCommands } from "./statusbar";
const timeout = (millis: number) => new Promise(c => setTimeout(c, millis));
......@@ -404,6 +405,11 @@ export class Repository implements Disposable {
this.disposables.push(new AutoFetcher(this));
const statusBar = new StatusBarCommands(this);
this.disposables.push(statusBar);
statusBar.onDidChange(() => this._sourceControl.statusBarCommands = statusBar.commands, null, this.disposables);
this._sourceControl.statusBarCommands = statusBar.commands;
this.updateCommitTemplate();
this.status();
}
......
......@@ -16,7 +16,7 @@ import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { StatusUpdater } from './scmActivity';
import { StatusUpdater, StatusBarController } from './scmActivity';
class OpenSCMViewletAction extends ToggleViewletAction {
......@@ -46,6 +46,9 @@ Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets)
Registry.as(WorkbenchExtensions.Workbench)
.registerWorkbenchContribution(StatusUpdater);
Registry.as(WorkbenchExtensions.Workbench)
.registerWorkbenchContribution(StatusBarController);
// Register Action to Open Viewlet
Registry.as<IWorkbenchActionRegistry>(WorkbenchActionExtensions.WorkbenchActions).registerWorkbenchAction(
new SyncActionDescriptor(OpenSCMViewletAction, VIEWLET_ID, localize('toggleSCMViewlet', "Show SCM"), {
......
......@@ -12,10 +12,11 @@ import { VIEWLET_ID } from 'vs/workbench/parts/scm/common/scm';
import { ISCMService, ISCMRepository } from 'vs/workbench/services/scm/common/scm';
import { IActivityBarService, NumberBadge } from 'vs/workbench/services/activity/common/activityBarService';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IStatusbarService, StatusbarAlignment as MainThreadStatusBarAlignment } from 'vs/platform/statusbar/common/statusbar';
export class StatusUpdater implements IWorkbenchContribution {
static ID = 'vs.scm.statusUpdater';
private static ID = 'vs.scm.statusUpdater';
private badgeDisposable: IDisposable = EmptyDisposable;
private disposables: IDisposable[] = [];
......@@ -25,18 +26,14 @@ export class StatusUpdater implements IWorkbenchContribution {
@IActivityBarService private activityBarService: IActivityBarService
) {
this.scmService.onDidAddRepository(this.onDidAddRepository, this, this.disposables);
this.render(this.scmService.repositories);
}
getId(): string {
return StatusUpdater.ID;
this.render();
}
private onDidAddRepository(repository: ISCMRepository): void {
const changeDisposable = repository.provider.onDidChange(() => this.render(this.scmService.repositories));
const changeDisposable = repository.provider.onDidChange(() => this.render());
const onDidRemoveThisRepository = filterEvent(this.scmService.onDidRemoveRepository, r => r === repository);
const removeDisposable = onDidRemoveThisRepository(() => {
const onDidRemove = filterEvent(this.scmService.onDidRemoveRepository, e => e === repository);
const removeDisposable = onDidRemove(() => {
disposable.dispose();
this.disposables = this.disposables.filter(d => d !== removeDisposable);
});
......@@ -45,8 +42,12 @@ export class StatusUpdater implements IWorkbenchContribution {
this.disposables.push(disposable);
}
private render(repositories: ISCMRepository[]): void {
const count = repositories.reduce((r, repository) => {
getId(): string {
return StatusUpdater.ID;
}
private render(): void {
const count = this.scmService.repositories.reduce((r, repository) => {
if (typeof repository.provider.count === 'number') {
return r + repository.provider.count;
} else {
......@@ -67,3 +68,68 @@ export class StatusUpdater implements IWorkbenchContribution {
this.disposables = dispose(this.disposables);
}
}
export class StatusBarController implements IWorkbenchContribution {
private static ID = 'vs.scm.statusBarController';
private statusBarDisposable: IDisposable = EmptyDisposable;
private focusDisposable: IDisposable = EmptyDisposable;
private disposables: IDisposable[] = [];
constructor(
@ISCMService private scmService: ISCMService,
@IStatusbarService private statusbarService: IStatusbarService
) {
this.scmService.onDidAddRepository(this.onDidAddRepository, this, this.disposables);
if (this.scmService.repositories.length > 0) {
this.onDidFocusRepository(this.scmService.repositories[0]);
}
}
getId(): string {
return StatusBarController.ID;
}
private onDidAddRepository(repository: ISCMRepository): void {
const changeDisposable = repository.onDidFocus(() => this.onDidFocusRepository(repository));
const onDidRemove = filterEvent(this.scmService.onDidRemoveRepository, e => e === repository);
const removeDisposable = onDidRemove(() => {
disposable.dispose();
this.disposables = this.disposables.filter(d => d !== removeDisposable);
});
const disposable = combinedDisposable([changeDisposable, removeDisposable]);
this.disposables.push(disposable);
if (this.scmService.repositories.length === 1) {
this.onDidFocusRepository(repository);
}
}
private onDidFocusRepository(repository: ISCMRepository): void {
this.focusDisposable.dispose();
this.focusDisposable = repository.provider.onDidChange(() => this.render(repository));
this.render(repository);
}
private render(repository: ISCMRepository): void {
this.statusBarDisposable.dispose();
const commands = repository.provider.statusBarCommands || [];
const disposables = commands.map(c => this.statusbarService.addEntry({
text: c.title,
tooltip: c.tooltip,
command: c.id
}, MainThreadStatusBarAlignment.LEFT, 10000));
this.statusBarDisposable = combinedDisposable(disposables);
}
dispose(): void {
this.focusDisposable.dispose();
this.statusBarDisposable.dispose();
this.disposables = dispose(this.disposables);
}
}
\ No newline at end of file
......@@ -14,7 +14,7 @@ import { onUnexpectedError } from 'vs/base/common/errors';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Builder } from 'vs/base/browser/builder';
import { ComposedViewsViewlet, CollapsibleView, IViewletViewOptions, IView, IViewOptions } from 'vs/workbench/parts/views/browser/views';
import { append, $, toggleClass } from 'vs/base/browser/dom';
import { append, $, toggleClass, trackFocus } from 'vs/base/browser/dom';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { List } from 'vs/base/browser/ui/list/listWidget';
import { IDelegate, IRenderer, IListContextMenuEvent } from 'vs/base/browser/ui/list/list';
......@@ -278,8 +278,11 @@ class SourceControlView extends CollapsibleView {
}
renderBody(container: HTMLElement): void {
// Input
const focusTracker = trackFocus(container);
this.disposables.push(focusTracker.addFocusListener(() => this.repository.focus()));
this.disposables.push(focusTracker);
// Input
this.inputBoxContainer = append(container, $('.scm-editor'));
this.inputBox = new InputBox(this.inputBoxContainer, this.contextViewService, {
......
......@@ -17,7 +17,6 @@ export interface IBaselineResourceProvider {
}
export const ISCMService = createDecorator<ISCMService>('scm');
export const DefaultSCMProviderIdStorageKey = 'settings.workspace.scm.defaultProviderId';
export interface ISCMResourceDecorations {
icon?: URI;
......@@ -62,8 +61,10 @@ export interface ISCMInput {
}
export interface ISCMRepository extends IDisposable {
readonly onDidFocus: Event<void>;
readonly provider: ISCMProvider;
readonly input: ISCMInput;
focus(): void;
}
export interface ISCMService {
......@@ -74,7 +75,6 @@ export interface ISCMService {
readonly onDidChangeRepository: Event<ISCMRepository>;
readonly repositories: ISCMRepository[];
activeRepository: ISCMRepository | undefined;
registerSCMProvider(provider: ISCMProvider): ISCMRepository;
}
\ No newline at end of file
......@@ -5,12 +5,9 @@
'use strict';
import { IDisposable, toDisposable, empty as EmptyDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import Event, { Emitter } from 'vs/base/common/event';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IStatusbarService, StatusbarAlignment as MainThreadStatusBarAlignment } from 'vs/platform/statusbar/common/statusbar';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { ISCMService, ISCMProvider, ISCMInput, ISCMRepository, DefaultSCMProviderIdStorageKey } from './scm';
import { ISCMService, ISCMProvider, ISCMInput, ISCMRepository } from './scm';
class SCMInput implements ISCMInput {
......@@ -31,6 +28,9 @@ class SCMInput implements ISCMInput {
class SCMRepository implements ISCMRepository {
private _onDidFocus = new Emitter<void>();
readonly onDidFocus: Event<void> = this._onDidFocus.event;
readonly input: ISCMInput = new SCMInput();
constructor(
......@@ -38,6 +38,10 @@ class SCMRepository implements ISCMRepository {
private disposable: IDisposable
) { }
focus(): void {
this._onDidFocus.fire();
}
dispose(): void {
this.disposable.dispose();
this.provider.dispose();
......@@ -48,20 +52,6 @@ export class SCMService implements ISCMService {
_serviceBrand;
private activeProviderDisposable: IDisposable = EmptyDisposable;
private statusBarDisposable: IDisposable = EmptyDisposable;
private _activeRepository: ISCMRepository | undefined;
get activeRepository(): ISCMRepository | undefined {
return this._activeRepository;
}
set activeRepository(repository: ISCMRepository | undefined) {
this.setActiveSCMProvider(repository);
this.storageService.store(DefaultSCMProviderIdStorageKey, repository.provider.contextValue, StorageScope.WORKSPACE);
}
private _providerIds = new Set<string>();
private _repositories: ISCMRepository[] = [];
get repositories(): ISCMRepository[] { return [...this._repositories]; }
......@@ -75,32 +65,7 @@ export class SCMService implements ISCMService {
private _onDidChangeProvider = new Emitter<ISCMRepository>();
get onDidChangeRepository(): Event<ISCMRepository> { return this._onDidChangeProvider.event; }
constructor(
@IContextKeyService contextKeyService: IContextKeyService,
@IStorageService private storageService: IStorageService,
@IStatusbarService private statusbarService: IStatusbarService
) { }
private setActiveSCMProvider(repository: ISCMRepository): void {
this.activeProviderDisposable.dispose();
if (!repository) {
throw new Error('invalid provider');
}
if (repository && this._repositories.indexOf(repository) === -1) {
throw new Error('Provider not registered');
}
this._activeRepository = repository;
const provider = repository.provider;
this.activeProviderDisposable = provider.onDidChange(() => this.onDidProviderChange(provider));
this.onDidProviderChange(provider);
this._onDidChangeProvider.fire(repository);
}
constructor() { }
registerSCMProvider(provider: ISCMProvider): ISCMRepository {
if (this._providerIds.has(provider.id)) {
......@@ -118,38 +83,13 @@ export class SCMService implements ISCMService {
this._providerIds.delete(provider.id);
this._repositories.splice(index, 1);
if (this.activeRepository === repository) {
this.activeRepository = this._repositories[0];
}
this._onDidRemoveProvider.fire(repository);
});
const repository = new SCMRepository(provider, disposable);
this._repositories.push(repository);
const defaultProviderId = this.storageService.get(DefaultSCMProviderIdStorageKey, StorageScope.WORKSPACE);
if (this._repositories.length === 1 || defaultProviderId === provider.contextValue) {
this.setActiveSCMProvider(repository);
}
this._onDidAddProvider.fire(repository);
return repository;
}
private onDidProviderChange(provider: ISCMProvider): void {
this.statusBarDisposable.dispose();
const commands = provider.statusBarCommands || [];
const disposables = commands.map(c => this.statusbarService.addEntry({
text: c.title,
tooltip: c.tooltip,
command: c.id
}, MainThreadStatusBarAlignment.LEFT, 10000));
this.statusBarDisposable = combinedDisposable(disposables);
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册