提交 37ae1348 编写于 作者: C Christof Marti

'Open Folder' hints in viewlets when no folder open

上级 817beafe
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import { Action } from 'vs/base/common/actions';
import nls = require('vs/nls');
import { IWindowService } from 'vs/platform/windows/common/windows';
export class OpenFolderAction extends Action {
static ID = 'workbench.action.files.openFolder';
static LABEL = nls.localize('openFolder', "Open Folder...");
constructor(
id: string,
label: string,
@IWindowService private windowService: IWindowService
) {
super(id, label);
}
run(): TPromise<any> {
return this.windowService.openFolderPicker();
}
}
export class OpenFileFolderAction extends Action {
static ID = 'workbench.action.files.openFileFolder';
static LABEL = nls.localize('openFileFolder', "Open...");
constructor(
id: string,
label: string,
@IWindowService private windowService: IWindowService
) {
super(id, label);
}
run(): TPromise<any> {
return this.windowService.openFileFolderPicker();
}
}
......@@ -5,6 +5,7 @@
import 'vs/css!./media/debugViewlet';
import * as nls from 'vs/nls';
import * as errors from 'vs/base/common/errors';
import { $, Builder, Dimension } from 'vs/base/browser/builder';
import { TPromise } from 'vs/base/common/winjs.base';
import * as lifecycle from 'vs/base/common/lifecycle';
......@@ -22,6 +23,9 @@ import { IProgressService, IProgressRunner } from 'vs/platform/progress/common/p
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IStorageService } from 'vs/platform/storage/common/storage';
import env = require('vs/base/common/platform');
import { Button } from 'vs/base/browser/ui/button/button';
import { OpenFolderAction, OpenFileFolderAction } from 'vs/workbench/browser/actions/fileActions';
export class DebugViewlet extends Viewlet {
......@@ -33,6 +37,7 @@ export class DebugViewlet extends Viewlet {
private $el: Builder;
private splitView: SplitView;
private views: IViewletView[];
private openFolderButton: Button;
private lastFocusedView: IViewletView;
......@@ -78,12 +83,27 @@ export class DebugViewlet extends Viewlet {
this.lastFocusedView = view;
}));
} else {
this.$el.append($([
const noworkspace = $([
'<div class="noworkspace-view">',
'<p>', nls.localize('noWorkspace', "There is no currently opened folder."), '</p>',
'<p>', nls.localize('noWorkspaceHelp', "You have not yet opened a folder."), '</p>',
'<p>', nls.localize('pleaseRestartToDebug', "Open a folder in order to start debugging."), '</p>',
'</div>'
].join('')));
].join(''));
this.openFolderButton = new Button(noworkspace);
this.openFolderButton.label = nls.localize('openFolder', "Open Folder");
this.openFolderButton.addListener2('click', () => {
const actionClass = env.isMacintosh ? OpenFileFolderAction : OpenFolderAction;
const action = this.instantiationService.createInstance<string, string, IAction>(actionClass, actionClass.ID, actionClass.LABEL);
this.actionRunner.run(action).done(() => {
action.dispose();
}, err => {
action.dispose();
errors.onUnexpectedError(err);
});
});
this.$el.append(noworkspace);
}
return TPromise.as(null);
......@@ -111,6 +131,11 @@ export class DebugViewlet extends Viewlet {
if (this.views.length > 0) {
this.views[0].focusBody();
return;
}
if (this.openFolderButton) {
this.openFolderButton.getElement().focus();
}
}
......
......@@ -189,7 +189,7 @@ export class ExplorerViewlet extends Viewlet {
// No workspace
else {
this.emptyView = explorerOrEmptyView = this.instantiationService.createInstance(EmptyView);
this.emptyView = explorerOrEmptyView = this.instantiationService.createInstance(EmptyView, this.getActionRunner());
}
if (this.openEditorsVisible) {
......
......@@ -5,23 +5,23 @@
'use strict';
import nls = require('vs/nls');
import * as errors from 'vs/base/common/errors';
import env = require('vs/base/common/platform');
import DOM = require('vs/base/browser/dom');
import { TPromise } from 'vs/base/common/winjs.base';
import { IAction, Action } from 'vs/base/common/actions';
import { IActionRunner, IAction } from 'vs/base/common/actions';
import { Button } from 'vs/base/browser/ui/button/button';
import { $ } from 'vs/base/browser/builder';
import { IActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { CollapsibleView } from 'vs/base/browser/ui/splitview/splitview';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { Registry } from 'vs/platform/platform';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actionRegistry';
import { OpenFolderAction, OpenFileFolderAction } from 'vs/workbench/browser/actions/fileActions';
export class EmptyView extends CollapsibleView {
private openFolderButton: Button;
constructor( @ITelemetryService private telemetryService: ITelemetryService,
constructor(
private actionRunner: IActionRunner,
@IInstantiationService private instantiationService: IInstantiationService
) {
super({
......@@ -46,7 +46,14 @@ export class EmptyView extends CollapsibleView {
this.openFolderButton = new Button(section);
this.openFolderButton.label = nls.localize('openFolder', "Open Folder");
this.openFolderButton.addListener2('click', () => {
this.runWorkbenchAction(env.isMacintosh ? 'workbench.action.files.openFileFolder' : 'workbench.action.files.openFolder');
const actionClass = env.isMacintosh ? OpenFileFolderAction : OpenFolderAction;
const action = this.instantiationService.createInstance<string, string, IAction>(actionClass, actionClass.ID, actionClass.LABEL);
this.actionRunner.run(action).done(() => {
action.dispose();
}, err => {
action.dispose();
errors.onUnexpectedError(err);
});
});
}
......@@ -54,16 +61,6 @@ export class EmptyView extends CollapsibleView {
// no-op
}
private runWorkbenchAction(actionId: string): void {
this.telemetryService.publicLog('workbenchActionExecuted', { id: actionId, from: 'explorer' });
let actionRegistry = <IWorkbenchActionRegistry>Registry.as(Extensions.WorkbenchActions);
let actionDescriptor = actionRegistry.getWorkbenchAction(actionId);
let action = <Action>this.instantiationService.createInstance(actionDescriptor.syncDescriptor);
return action.run().done(() => action.dispose());
}
public create(): TPromise<void> {
return TPromise.as(null);
}
......
......@@ -141,42 +141,6 @@ export class OpenFileAction extends Action {
}
}
export class OpenFolderAction extends Action {
static ID = 'workbench.action.files.openFolder';
static LABEL = nls.localize('openFolder', "Open Folder...");
constructor(
id: string,
label: string,
@IWindowService private windowService: IWindowService
) {
super(id, label);
}
run(): TPromise<any> {
return this.windowService.openFolderPicker();
}
}
export class OpenFileFolderAction extends Action {
static ID = 'workbench.action.files.openFileFolder';
static LABEL = nls.localize('openFileFolder', "Open...");
constructor(
id: string,
label: string,
@IWindowService private windowService: IWindowService
) {
super(id, label);
}
run(): TPromise<any> {
return this.windowService.openFileFolderPicker();
}
}
export class ShowOpenedFileInNewWindow extends Action {
public static ID = 'workbench.action.files.showOpenedFileInNewWindow';
......
......@@ -16,7 +16,8 @@ import { asFileResource } from 'vs/workbench/parts/files/common/files';
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
import { GlobalNewUntitledFileAction, SaveFileAsAction } from 'vs/workbench/parts/files/browser/fileActions';
import { DirtyFilesTracker } from 'vs/workbench/parts/files/electron-browser/dirtyFilesTracker';
import { OpenFolderAction, OpenFileAction, OpenFileFolderAction, ShowOpenedFileInNewWindow, GlobalRevealInOSAction, GlobalCopyPathAction, CopyPathAction, RevealInOSAction } from 'vs/workbench/parts/files/electron-browser/electronFileActions';
import { OpenFileAction, ShowOpenedFileInNewWindow, GlobalRevealInOSAction, GlobalCopyPathAction, CopyPathAction, RevealInOSAction } from 'vs/workbench/parts/files/electron-browser/electronFileActions';
import { OpenFolderAction, OpenFileFolderAction } from 'vs/workbench/browser/actions/fileActions';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
......
......@@ -60,7 +60,7 @@ export class GitViewlet
this.instantiationService.createInstance(empty.EmptyView, this, this.getActionRunner()),
this.instantiationService.createInstance(gitless.GitlessView),
new notroot.NotRootView(),
new noworkspace.NoWorkspaceView(),
this.instantiationService.createInstance(noworkspace.NoWorkspaceView, this.getActionRunner()),
new DisabledView(),
this.instantiationService.createInstance(HugeView)
];
......
......@@ -95,7 +95,7 @@ export class EmptyView extends EventEmitter.EventEmitter implements GitView.IVie
var initSection = $('.section').appendTo(this.$el);
this.initButton = new Button(initSection);
this.initButton.label = nls.localize('gitinit', 'Initialize git repository');
this.initButton.label = nls.localize('gitinit', 'Initialize Git Repository');
this.initButton.addListener2('click', (e) => {
DOM.EventHelper.stop(e);
......
......@@ -10,14 +10,3 @@
.git-viewlet > .noworkspace-view > p {
line-height: 1.5em;
}
.git-viewlet > .noworkspace-view .code {
display: inline;
}
.git-viewlet > .noworkspace-view a
{
color: inherit;
font-weight: bold;
text-decoration: underline;
}
......@@ -7,11 +7,16 @@
import 'vs/css!./noworkspaceView';
import nls = require('vs/nls');
import * as errors from 'vs/base/common/errors';
import winjs = require('vs/base/common/winjs.base');
import ee = require('vs/base/common/eventEmitter');
import env = require('vs/base/common/platform');
import view = require('vs/workbench/parts/git/browser/views/view');
import builder = require('vs/base/browser/builder');
import actions = require('vs/base/common/actions');
import { Button } from 'vs/base/browser/ui/button/button';
import { IActionRunner, IAction } from 'vs/base/common/actions';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { OpenFolderAction, OpenFileFolderAction } from 'vs/workbench/browser/actions/fileActions';
const $ = builder.$;
export class NoWorkspaceView
......@@ -19,6 +24,14 @@ export class NoWorkspaceView
implements view.IView {
public ID = 'noworkspace';
private _element: HTMLElement;
private _openFolderButton: Button;
constructor(
private actionRunner: IActionRunner,
@IInstantiationService private instantiationService: IInstantiationService,
) {
super();
}
public get element(): HTMLElement {
if (!this._element) {
......@@ -31,14 +44,29 @@ export class NoWorkspaceView
private render(): void {
this._element = $([
'<div class="noworkspace-view">',
'<p>', nls.localize('noWorkspace', "There is no currently opened folder."), '</p>',
'<p>', nls.localize('noWorkspaceHelp', "You have not yet opened a folder."), '</p>',
'<p>', nls.localize('pleaseRestart', "Open a folder with a Git repository in order to access Git features."), '</p>',
'</div>'
].join('')).getHTMLElement();
this._openFolderButton = new Button(this._element);
this._openFolderButton.label = nls.localize('openFolder', "Open Folder");
this._openFolderButton.addListener2('click', () => {
const actionClass = env.isMacintosh ? OpenFileFolderAction : OpenFolderAction;
const action = this.instantiationService.createInstance<string, string, IAction>(actionClass, actionClass.ID, actionClass.LABEL);
this.actionRunner.run(action).done(() => {
action.dispose();
}, err => {
action.dispose();
errors.onUnexpectedError(err);
});
});
}
public focus(): void {
return;
if (this._openFolderButton) {
this._openFolderButton.getElement().focus();
}
}
public layout(dimension: builder.Dimension): void {
......@@ -53,11 +81,11 @@ export class NoWorkspaceView
return null;
}
public getActions(): actions.IAction[] {
public getActions(): IAction[] {
return [];
}
public getSecondaryActions(): actions.IAction[] {
public getSecondaryActions(): IAction[] {
return [];
}
}
\ No newline at end of file
......@@ -152,6 +152,10 @@
padding-top: 2px;
}
.search-viewlet .message p:first-child {
margin-top: 0;
}
.search-viewlet .filematch {
position: relative;
line-height: 22px;
......
......@@ -13,6 +13,7 @@ import lifecycle = require('vs/base/common/lifecycle');
import errors = require('vs/base/common/errors');
import aria = require('vs/base/browser/ui/aria/aria');
import { IExpression } from 'vs/base/common/glob';
import env = require('vs/base/common/platform');
import { isFunction } from 'vs/base/common/types';
import URI from 'vs/base/common/uri';
import strings = require('vs/base/common/strings');
......@@ -52,6 +53,7 @@ import { RefreshAction, CollapseAllAction, ClearSearchResultsAction, ConfigureGl
import { IReplaceService } from 'vs/workbench/parts/search/common/replace';
import Severity from 'vs/base/common/severity';
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import { OpenFolderAction, OpenFileFolderAction } from 'vs/workbench/browser/actions/fileActions';
import * as Constants from 'vs/workbench/parts/search/common/constants';
export class SearchViewlet extends Viewlet {
......@@ -219,6 +221,9 @@ export class SearchViewlet extends Viewlet {
}).getHTMLElement();
this.messages = builder.div({ 'class': 'messages' }).hide().clone();
if (!this.contextService.getWorkspace()) {
this.searchWithoutFolderMessage(this.clearMessage());
}
this.createSearchResultsView(builder);
......@@ -350,7 +355,8 @@ export class SearchViewlet extends Viewlet {
this.searchWidget.setReplaceAllActionState(false);
this.viewModel.searchResult.replaceAll(progressRunner).then(() => {
progressRunner.done();
this.showMessage(afterReplaceAllMessage);
this.clearMessage()
.p({ text: afterReplaceAllMessage });
}, (error) => {
progressRunner.done();
errors.isPromiseCanceledError(error);
......@@ -359,8 +365,10 @@ export class SearchViewlet extends Viewlet {
}
}
private showMessage(text: string): Builder {
return this.messages.empty().show().asContainer().div({ 'class': 'message', text: text });
private clearMessage(): Builder {
return this.messages.empty().show()
.asContainer().div({ 'class': 'message' })
.asContainer();
}
private createSearchResultsView(builder: Builder): void {
......@@ -572,6 +580,9 @@ export class SearchViewlet extends Viewlet {
public clearSearchResults(): void {
this.viewModel.searchResult.clear();
this.showEmptyStage();
if (!this.contextService.getWorkspace()) {
this.searchWithoutFolderMessage(this.clearMessage());
}
this.searchWidget.clear();
this.viewModel.cancelSearch();
}
......@@ -838,10 +849,11 @@ export class SearchViewlet extends Viewlet {
this.tree.onHidden();
this.results.hide();
let div = this.showMessage(message);
const div = this.clearMessage();
const p = $(div).p({ text: message });
if (!completed) {
$(div).a({
$(p).a({
'class': ['pointer', 'prominent'],
text: nls.localize('rerunSearch.message', "Search again")
}).on(dom.EventType.CLICK, (e: MouseEvent) => {
......@@ -850,7 +862,7 @@ export class SearchViewlet extends Viewlet {
this.onQueryChanged(true);
});
} else if (hasIncludes || hasExcludes) {
$(div).a({
$(p).a({
'class': ['pointer', 'prominent'],
'tabindex': '0',
text: nls.localize('rerunSearchInAll.message', "Search again in all files")
......@@ -863,16 +875,24 @@ export class SearchViewlet extends Viewlet {
this.onQueryChanged(true);
});
} else {
$(div).a({
$(p).a({
'class': ['pointer', 'prominent'],
'tabindex': '0',
text: nls.localize('openSettings.message', "Open Settings")
}).on(dom.EventType.CLICK, (e: MouseEvent) => {
dom.EventHelper.stop(e, false);
this.preferencesService.openWorkspaceSettings().done(() => null, errors.onUnexpectedError);
if (this.contextService.getWorkspace()) {
this.preferencesService.openWorkspaceSettings().done(() => null, errors.onUnexpectedError);
} else {
this.preferencesService.openGlobalSettings().done(() => null, errors.onUnexpectedError);
}
});
}
if (!this.contextService.getWorkspace()) {
this.searchWithoutFolderMessage(div);
}
} else {
this.viewModel.searchResult.toggleHighlights(true); // show highlights
......@@ -949,6 +969,26 @@ export class SearchViewlet extends Viewlet {
this.viewModel.search(query).done(onComplete, onError, onProgress);
}
private searchWithoutFolderMessage(div: Builder): void {
$(div).p({ text: nls.localize('searchWithoutFolder', "You have not yet opened a folder. Only open files are currently searched - ") })
.asContainer().a({
'class': ['pointer', 'prominent'],
'tabindex': '0',
text: nls.localize('openFolder', "Open Folder")
}).on(dom.EventType.CLICK, (e: MouseEvent) => {
dom.EventHelper.stop(e, false);
const actionClass = env.isMacintosh ? OpenFileFolderAction : OpenFolderAction;
const action = this.instantiationService.createInstance<string, string, IAction>(actionClass, actionClass.ID, actionClass.LABEL);
this.actionRunner.run(action).done(() => {
action.dispose();
}, err => {
action.dispose();
errors.onUnexpectedError(err);
});
});
}
private showEmptyStage(): void {
// disable 'result'-actions
......
......@@ -20,7 +20,8 @@ import { GlobalQuickOpenAction } from 'vs/workbench/browser/parts/quickopen/quic
import { KeybindingsReferenceAction, OpenRecentAction } from 'vs/workbench/electron-browser/actions';
import { ShowRecommendedKeymapExtensionsAction } from 'vs/workbench/parts/extensions/browser/extensionsActions';
import { GlobalNewUntitledFileAction } from 'vs/workbench/parts/files/browser/fileActions';
import { OpenFolderAction, OpenFileAction, OpenFileFolderAction } from 'vs/workbench/parts/files/electron-browser/electronFileActions';
import { OpenFileAction } from 'vs/workbench/parts/files/electron-browser/electronFileActions';
import { OpenFolderAction, OpenFileFolderAction } from 'vs/workbench/browser/actions/fileActions';
import { ShowAllCommandsAction } from 'vs/workbench/parts/quickopen/browser/commandsHandler';
import { Parts, IPartService } from 'vs/workbench/services/part/common/partService';
import { StartAction } from 'vs/workbench/parts/debug/browser/debugActions';
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册