提交 15b1f599 编写于 作者: B Benjamin Pasero

less use of toResource with filter: file

上级 d99c7d8e
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
import * as paths from 'vs/base/common/paths'; import * as paths from 'vs/base/common/paths';
import uri from 'vs/base/common/uri'; import uri from 'vs/base/common/uri';
import { equalsIgnoreCase } from 'vs/base/common/strings';
export function basenameOrAuthority(resource: uri): string { export function basenameOrAuthority(resource: uri): string {
return paths.basename(resource.fsPath) || resource.authority; return paths.basename(resource.fsPath) || resource.authority;
...@@ -19,6 +20,23 @@ export function isEqualOrParent(first: uri, second: uri, ignoreCase?: boolean): ...@@ -19,6 +20,23 @@ export function isEqualOrParent(first: uri, second: uri, ignoreCase?: boolean):
return false; return false;
} }
export function isEqual(first: uri, second: uri, ignoreCase?: boolean): boolean {
const identityEquals = (first === second);
if (identityEquals) {
return true;
}
if (!first || !second) {
return false;
}
if (ignoreCase) {
return equalsIgnoreCase(first.toString(), second.toString());
}
return first.toString() === second.toString();
}
export function dirname(resource: uri): uri { export function dirname(resource: uri): uri {
return resource.with({ return resource.with({
path: paths.dirname(resource.path) path: paths.dirname(resource.path)
......
...@@ -15,6 +15,7 @@ import Event from 'vs/base/common/event'; ...@@ -15,6 +15,7 @@ import Event from 'vs/base/common/event';
import { beginsWithIgnoreCase } from 'vs/base/common/strings'; import { beginsWithIgnoreCase } from 'vs/base/common/strings';
import { IProgress } from 'vs/platform/progress/common/progress'; import { IProgress } from 'vs/platform/progress/common/progress';
import { IDisposable } from 'vs/base/common/lifecycle'; import { IDisposable } from 'vs/base/common/lifecycle';
import { isEqualOrParent, isEqual } from 'vs/base/common/resources';
export const IFileService = createDecorator<IFileService>('fileService'); export const IFileService = createDecorator<IFileService>('fileService');
...@@ -274,10 +275,10 @@ export class FileChangesEvent extends events.Event { ...@@ -274,10 +275,10 @@ export class FileChangesEvent extends events.Event {
// For deleted also return true when deleted folder is parent of target path // For deleted also return true when deleted folder is parent of target path
if (type === FileChangeType.DELETED) { if (type === FileChangeType.DELETED) {
return paths.isEqualOrParent(resource.fsPath, change.resource.fsPath, !isLinux /* ignorecase */); return isEqualOrParent(resource, change.resource, !isLinux /* ignorecase */);
} }
return paths.isEqual(resource.fsPath, change.resource.fsPath, !isLinux /* ignorecase */); return isEqual(resource, change.resource, !isLinux /* ignorecase */);
}); });
} }
......
...@@ -696,7 +696,7 @@ export class EditorStatus implements IStatusbarItem { ...@@ -696,7 +696,7 @@ export class EditorStatus implements IStatusbarItem {
private onResourceEncodingChange(resource: uri): void { private onResourceEncodingChange(resource: uri): void {
const activeEditor = this.editorService.getActiveEditor(); const activeEditor = this.editorService.getActiveEditor();
if (activeEditor) { if (activeEditor) {
const activeResource = toResource(activeEditor.input, { supportSideBySide: true, filter: ['file', 'untitled'] }); const activeResource = toResource(activeEditor.input, { supportSideBySide: true });
if (activeResource && activeResource.toString() === resource.toString()) { if (activeResource && activeResource.toString() === resource.toString()) {
return this.onEncodingChange(<IBaseEditor>activeEditor); // only update if the encoding changed for the active resource return this.onEncodingChange(<IBaseEditor>activeEditor); // only update if the encoding changed for the active resource
} }
...@@ -766,6 +766,7 @@ export class ChangeModeAction extends Action { ...@@ -766,6 +766,7 @@ export class ChangeModeAction extends Action {
@IPreferencesService private preferencesService: IPreferencesService, @IPreferencesService private preferencesService: IPreferencesService,
@IInstantiationService private instantiationService: IInstantiationService, @IInstantiationService private instantiationService: IInstantiationService,
@ICommandService private commandService: ICommandService, @ICommandService private commandService: ICommandService,
@IUntitledEditorService private untitledEditorService: IUntitledEditorService,
@IConfigurationEditingService private configurationEditService: IConfigurationEditingService @IConfigurationEditingService private configurationEditService: IConfigurationEditingService
) { ) {
super(actionId, actionLabel); super(actionId, actionLabel);
...@@ -779,7 +780,10 @@ export class ChangeModeAction extends Action { ...@@ -779,7 +780,10 @@ export class ChangeModeAction extends Action {
} }
const textModel = editorWidget.getModel(); const textModel = editorWidget.getModel();
const fileResource = toResource(activeEditor.input, { supportSideBySide: true, filter: 'file' }); let resource = toResource(activeEditor.input, { supportSideBySide: true });
if (resource.scheme === 'untitled' && !this.untitledEditorService.hasAssociatedFilePath(resource)) {
resource = void 0; // no configuration for untitled resources (e.g. "Untitled-1")
}
// Compute mode // Compute mode
let currentModeId: string; let currentModeId: string;
...@@ -818,7 +822,7 @@ export class ChangeModeAction extends Action { ...@@ -818,7 +822,7 @@ export class ChangeModeAction extends Action {
}; };
}); });
if (fileResource) { if (resource) {
picks[0].separator = { border: true, label: nls.localize('languagesPicks', "languages (identifier)") }; picks[0].separator = { border: true, label: nls.localize('languagesPicks', "languages (identifier)") };
} }
...@@ -826,15 +830,14 @@ export class ChangeModeAction extends Action { ...@@ -826,15 +830,14 @@ export class ChangeModeAction extends Action {
let configureModeAssociations: IPickOpenEntry; let configureModeAssociations: IPickOpenEntry;
let configureModeSettings: IPickOpenEntry; let configureModeSettings: IPickOpenEntry;
let galleryAction: Action; let galleryAction: Action;
if (fileResource) { if (resource) {
const ext = paths.extname(fileResource.fsPath) || paths.basename(fileResource.fsPath); const ext = paths.extname(resource.fsPath) || paths.basename(resource.fsPath);
galleryAction = this.instantiationService.createInstance(ShowLanguageExtensionsAction, ext); galleryAction = this.instantiationService.createInstance(ShowLanguageExtensionsAction, ext);
if (galleryAction.enabled) { if (galleryAction.enabled) {
picks.unshift(galleryAction); picks.unshift(galleryAction);
} }
configureModeSettings = { label: nls.localize('configureModeSettings', "Configure '{0}' language based settings...", currentModeId) }; configureModeSettings = { label: nls.localize('configureModeSettings', "Configure '{0}' language based settings...", currentModeId) };
picks.unshift(configureModeSettings); picks.unshift(configureModeSettings);
configureModeAssociations = { label: nls.localize('configureAssociationsExt', "Configure File Association for '{0}'...", ext) }; configureModeAssociations = { label: nls.localize('configureAssociationsExt', "Configure File Association for '{0}'...", ext) };
...@@ -845,7 +848,8 @@ export class ChangeModeAction extends Action { ...@@ -845,7 +848,8 @@ export class ChangeModeAction extends Action {
const autoDetectMode: IPickOpenEntry = { const autoDetectMode: IPickOpenEntry = {
label: nls.localize('autoDetect', "Auto Detect") label: nls.localize('autoDetect', "Auto Detect")
}; };
if (fileResource) {
if (resource) {
picks.unshift(autoDetectMode); picks.unshift(autoDetectMode);
} }
...@@ -861,7 +865,7 @@ export class ChangeModeAction extends Action { ...@@ -861,7 +865,7 @@ export class ChangeModeAction extends Action {
// User decided to permanently configure associations, return right after // User decided to permanently configure associations, return right after
if (pick === configureModeAssociations) { if (pick === configureModeAssociations) {
this.configureFileAssociation(fileResource); this.configureFileAssociation(resource);
return; return;
} }
...@@ -896,7 +900,7 @@ export class ChangeModeAction extends Action { ...@@ -896,7 +900,7 @@ export class ChangeModeAction extends Action {
// Find mode // Find mode
let mode: TPromise<IMode>; let mode: TPromise<IMode>;
if (pick === autoDetectMode) { if (pick === autoDetectMode) {
mode = this.modeService.getOrCreateModeByFilenameOrFirstLine(toResource(activeEditor.input, { supportSideBySide: true, filter: ['file', 'untitled'] }).fsPath, textModel.getLineContent(1)); mode = this.modeService.getOrCreateModeByFilenameOrFirstLine(toResource(activeEditor.input, { supportSideBySide: true }).fsPath, textModel.getLineContent(1));
} else { } else {
mode = this.modeService.getOrCreateModeByLanguageName(pick.label); mode = this.modeService.getOrCreateModeByLanguageName(pick.label);
} }
...@@ -1111,12 +1115,12 @@ export class ChangeEncodingAction extends Action { ...@@ -1111,12 +1115,12 @@ export class ChangeEncodingAction extends Action {
return void 0; return void 0;
} }
const resource = toResource(activeEditor.input, { filter: ['file', 'untitled'], supportSideBySide: true }); const resource = toResource(activeEditor.input, { supportSideBySide: true });
return TPromise.timeout(50 /* quick open is sensitive to being opened so soon after another */) return TPromise.timeout(50 /* quick open is sensitive to being opened so soon after another */)
.then(() => { .then(() => {
if (!resource || resource.scheme !== 'file') { if (!resource || !this.fileService.canHandleResource(resource)) {
return TPromise.as(null); // encoding detection only possible for file resources return TPromise.as(null); // encoding detection only possible for resources the file service can handle
} }
return this.fileService.resolveContent(resource, { autoGuessEncoding: true, acceptTextOnly: true }).then(content => content.encoding, err => null); return this.fileService.resolveContent(resource, { autoGuessEncoding: true, acceptTextOnly: true }).then(content => content.encoding, err => null);
......
...@@ -670,12 +670,15 @@ export class TabsTitleControl extends TitleControl { ...@@ -670,12 +670,15 @@ export class TabsTitleControl extends TitleControl {
e.dataTransfer.effectAllowed = 'copyMove'; e.dataTransfer.effectAllowed = 'copyMove';
// Insert transfer accordingly // Insert transfer accordingly
const fileResource = toResource(editor, { supportSideBySide: true, filter: 'file' }); const resource = toResource(editor, { supportSideBySide: true });
if (fileResource) { if (resource) {
const resource = fileResource.toString(); const resourceStr = resource.toString();
e.dataTransfer.setData('URL', resource); // enables cross window DND of tabs e.dataTransfer.setData('URL', resourceStr); // enables cross window DND of tabs
e.dataTransfer.setData('DownloadURL', [MIME_BINARY, editor.getName(), resource].join(':')); // enables support to drag a tab as file to desktop
e.dataTransfer.setData('text/plain', getPathLabel(resource)); // enables dropping tab resource path into text controls e.dataTransfer.setData('text/plain', getPathLabel(resource)); // enables dropping tab resource path into text controls
if (resource.scheme === 'file') {
e.dataTransfer.setData('DownloadURL', [MIME_BINARY, editor.getName(), resourceStr].join(':')); // enables support to drag a tab as file to desktop
}
} }
})); }));
......
...@@ -195,7 +195,7 @@ export class TitlebarPart extends Part implements ITitleService { ...@@ -195,7 +195,7 @@ export class TitlebarPart extends Part implements ITitleService {
// Compute folder resource // Compute folder resource
// Single Root Workspace: always the root single workspace in this case // Single Root Workspace: always the root single workspace in this case
// Otherwise: root folder of the currently active file if any // Otherwise: root folder of the currently active file if any
let folder = this.contextService.getWorkbenchState() === WorkbenchState.FOLDER ? workspace.folders[0] : this.contextService.getWorkspaceFolder(toResource(input, { supportSideBySide: true, filter: 'file' })); let folder = this.contextService.getWorkbenchState() === WorkbenchState.FOLDER ? workspace.folders[0] : this.contextService.getWorkspaceFolder(toResource(input, { supportSideBySide: true }));
// Variables // Variables
const activeEditorShort = input ? input.getTitle(Verbosity.SHORT) : ''; const activeEditorShort = input ? input.getTitle(Verbosity.SHORT) : '';
......
...@@ -9,7 +9,6 @@ import Event, { Emitter } from 'vs/base/common/event'; ...@@ -9,7 +9,6 @@ import Event, { Emitter } from 'vs/base/common/event';
import * as editorCommon from 'vs/editor/common/editorCommon'; import * as editorCommon from 'vs/editor/common/editorCommon';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { toResource } from 'vs/workbench/common/editor'; import { toResource } from 'vs/workbench/common/editor';
import { isEqual } from 'vs/base/common/paths';
import { IRange } from 'vs/editor/common/core/range'; import { IRange } from 'vs/editor/common/core/range';
import { CursorChangeReason, ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents'; import { CursorChangeReason, ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
import { ModelDecorationOptions } from 'vs/editor/common/model/textModelWithDecorations'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModelWithDecorations';
...@@ -56,9 +55,9 @@ export class RangeHighlightDecorations implements IDisposable { ...@@ -56,9 +55,9 @@ export class RangeHighlightDecorations implements IDisposable {
} }
private getEditor(resourceRange: IRangeHighlightDecoration): editorCommon.ICommonCodeEditor { private getEditor(resourceRange: IRangeHighlightDecoration): editorCommon.ICommonCodeEditor {
const fileResource = toResource(this.editorService.getActiveEditorInput(), { filter: 'file' }); const resource = toResource(this.editorService.getActiveEditorInput());
if (fileResource) { if (resource) {
if (isEqual(fileResource.fsPath, resourceRange.resource.fsPath)) { if (resource.toString() === resourceRange.resource.toString()) {
return <editorCommon.ICommonCodeEditor>this.editorService.getActiveEditor().getControl(); return <editorCommon.ICommonCodeEditor>this.editorService.getActiveEditor().getControl();
} }
} }
......
...@@ -35,7 +35,7 @@ export const copyPathCommand = (accessor: ServicesAccessor, resource?: URI) => { ...@@ -35,7 +35,7 @@ export const copyPathCommand = (accessor: ServicesAccessor, resource?: URI) => {
const editorService = accessor.get(IWorkbenchEditorService); const editorService = accessor.get(IWorkbenchEditorService);
const activeEditor = editorService.getActiveEditor(); const activeEditor = editorService.getActiveEditor();
resource = activeEditor ? toResource(activeEditor.input, { supportSideBySide: true, filter: 'file' }) : void 0; resource = activeEditor ? toResource(activeEditor.input, { supportSideBySide: true }) : void 0;
if (activeEditor) { if (activeEditor) {
editorGroupService.focusGroup(activeEditor.position); // focus back to active editor group editorGroupService.focusGroup(activeEditor.position); // focus back to active editor group
} }
......
...@@ -266,10 +266,10 @@ export class FileEditorTracker implements IWorkbenchContribution { ...@@ -266,10 +266,10 @@ export class FileEditorTracker implements IWorkbenchContribution {
private handleUpdatesToVisibleBinaryEditors(e: FileChangesEvent): void { private handleUpdatesToVisibleBinaryEditors(e: FileChangesEvent): void {
const editors = this.editorService.getVisibleEditors(); const editors = this.editorService.getVisibleEditors();
editors.forEach(editor => { editors.forEach(editor => {
const fileResource = toResource(editor.input, { filter: 'file', supportSideBySide: true }); const resource = toResource(editor.input, { supportSideBySide: true });
// Binary editor that should reload from event // Binary editor that should reload from event
if (fileResource && editor.getId() === BINARY_FILE_EDITOR_ID && (e.contains(fileResource, FileChangeType.UPDATED) || e.contains(fileResource, FileChangeType.ADDED))) { if (resource && editor.getId() === BINARY_FILE_EDITOR_ID && (e.contains(resource, FileChangeType.UPDATED) || e.contains(resource, FileChangeType.ADDED))) {
this.editorService.openEditor(editor.input, { forceOpen: true, preserveFocus: true }, editor.position).done(null, errors.onUnexpectedError); this.editorService.openEditor(editor.input, { forceOpen: true, preserveFocus: true }, editor.position).done(null, errors.onUnexpectedError);
} }
}); });
...@@ -305,9 +305,9 @@ export class FileEditorTracker implements IWorkbenchContribution { ...@@ -305,9 +305,9 @@ export class FileEditorTracker implements IWorkbenchContribution {
private handleOutOfWorkspaceWatchers(): void { private handleOutOfWorkspaceWatchers(): void {
const visibleOutOfWorkspacePaths = new ResourceMap<URI>(); const visibleOutOfWorkspacePaths = new ResourceMap<URI>();
this.editorService.getVisibleEditors().map(editor => { this.editorService.getVisibleEditors().map(editor => {
return toResource(editor.input, { supportSideBySide: true, filter: 'file' }); return toResource(editor.input, { supportSideBySide: true });
}).filter(fileResource => { }).filter(resource => {
return !!fileResource && !this.contextService.isInsideWorkspace(fileResource); return !!resource && this.fileService.canHandleResource(resource) && !this.contextService.isInsideWorkspace(resource);
}).forEach(resource => { }).forEach(resource => {
visibleOutOfWorkspacePaths.set(resource, resource); visibleOutOfWorkspacePaths.set(resource, resource);
}); });
......
...@@ -47,7 +47,7 @@ export class MarkersPanel extends Panel { ...@@ -47,7 +47,7 @@ export class MarkersPanel extends Panel {
private delayedRefresh: Delayer<void>; private delayedRefresh: Delayer<void>;
private lastSelectedRelativeTop: number = 0; private lastSelectedRelativeTop: number = 0;
private currentActiveFile: URI = null; private currentActiveResource: URI = null;
private hasToAutoReveal: boolean; private hasToAutoReveal: boolean;
private tree: Tree.ITree; private tree: Tree.ITree;
...@@ -63,7 +63,7 @@ export class MarkersPanel extends Panel { ...@@ -63,7 +63,7 @@ export class MarkersPanel extends Panel {
private messageBox: HTMLElement; private messageBox: HTMLElement;
private markerFocusContextKey: IContextKey<boolean>; private markerFocusContextKey: IContextKey<boolean>;
private currentFileGotAddedToMarkersData: boolean = false; private currentResourceGotAddedToMarkersData: boolean = false;
constructor( constructor(
@IInstantiationService private instantiationService: IInstantiationService, @IInstantiationService private instantiationService: IInstantiationService,
...@@ -256,31 +256,31 @@ export class MarkersPanel extends Panel { ...@@ -256,31 +256,31 @@ export class MarkersPanel extends Panel {
} }
private onMarkerChanged(changedResources: URI[]) { private onMarkerChanged(changedResources: URI[]) {
this.currentFileGotAddedToMarkersData = this.currentFileGotAddedToMarkersData || this.isCurrentFileGotAddedToMarkersData(changedResources); this.currentResourceGotAddedToMarkersData = this.currentResourceGotAddedToMarkersData || this.isCurrentResourceGotAddedToMarkersData(changedResources);
this.updateResources(changedResources); this.updateResources(changedResources);
this.delayedRefresh.trigger(() => { this.delayedRefresh.trigger(() => {
this.refreshPanel(); this.refreshPanel();
this.updateRangeHighlights(); this.updateRangeHighlights();
if (this.currentFileGotAddedToMarkersData) { if (this.currentResourceGotAddedToMarkersData) {
this.autoReveal(); this.autoReveal();
this.currentFileGotAddedToMarkersData = false; this.currentResourceGotAddedToMarkersData = false;
} }
}); });
} }
private isCurrentFileGotAddedToMarkersData(changedResources: URI[]) { private isCurrentResourceGotAddedToMarkersData(changedResources: URI[]) {
if (!this.currentActiveFile) { if (!this.currentActiveResource) {
return false; return false;
} }
const resourceForCurrentActiveFile = this.getResourceForCurrentActiveFile(); const resourceForCurrentActiveResource = this.getResourceForCurrentActiveResource();
if (resourceForCurrentActiveFile) { if (resourceForCurrentActiveResource) {
return false; return false;
} }
return changedResources.some(r => r.toString() === this.currentActiveFile.toString()); return changedResources.some(r => r.toString() === this.currentActiveResource.toString());
} }
private onEditorsChanged(): void { private onEditorsChanged(): void {
this.currentActiveFile = toResource(this.editorService.getActiveEditorInput(), { filter: 'file' }); this.currentActiveResource = toResource(this.editorService.getActiveEditorInput());
this.autoReveal(); this.autoReveal();
} }
...@@ -340,7 +340,7 @@ export class MarkersPanel extends Panel { ...@@ -340,7 +340,7 @@ export class MarkersPanel extends Panel {
} }
private revealMarkersForCurrentActiveEditor(focus: boolean = false): void { private revealMarkersForCurrentActiveEditor(focus: boolean = false): void {
let currentActiveResource = this.getResourceForCurrentActiveFile(); let currentActiveResource = this.getResourceForCurrentActiveResource();
if (currentActiveResource) { if (currentActiveResource) {
if (this.tree.isExpanded(currentActiveResource) && this.hasSelectedMarkerFor(currentActiveResource)) { if (this.tree.isExpanded(currentActiveResource) && this.hasSelectedMarkerFor(currentActiveResource)) {
this.tree.reveal(this.tree.getSelection()[0], this.lastSelectedRelativeTop); this.tree.reveal(this.tree.getSelection()[0], this.lastSelectedRelativeTop);
...@@ -360,10 +360,10 @@ export class MarkersPanel extends Panel { ...@@ -360,10 +360,10 @@ export class MarkersPanel extends Panel {
} }
} }
private getResourceForCurrentActiveFile(): Resource { private getResourceForCurrentActiveResource(): Resource {
if (this.currentActiveFile) { if (this.currentActiveResource) {
let resources = this.markersModel.filteredResources.filter((resource): boolean => { let resources = this.markersModel.filteredResources.filter((resource): boolean => {
return this.currentActiveFile.toString() === resource.uri.toString(); return this.currentActiveResource.toString() === resource.uri.toString();
}); });
return resources.length > 0 ? resources[0] : null; return resources.length > 0 ? resources[0] : null;
} }
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
import nls = require('vs/nls'); import nls = require('vs/nls');
import DOM = require('vs/base/browser/dom'); import DOM = require('vs/base/browser/dom');
import errors = require('vs/base/common/errors'); import errors = require('vs/base/common/errors');
import paths = require('vs/base/common/paths');
import resources = require('vs/base/common/resources'); import resources = require('vs/base/common/resources');
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import URI from 'vs/base/common/uri'; import URI from 'vs/base/common/uri';
...@@ -634,9 +633,9 @@ export class ReplaceAction extends AbstractSearchAndReplaceAction { ...@@ -634,9 +633,9 @@ export class ReplaceAction extends AbstractSearchAndReplaceAction {
} }
private hasToOpenFile(): boolean { private hasToOpenFile(): boolean {
const file = toResource(this.editorService.getActiveEditorInput(), { filter: 'file' }); const file = toResource(this.editorService.getActiveEditorInput());
if (file) { if (file) {
return paths.isEqual(file.fsPath, this.element.parent().resource().fsPath); return file.toString() === this.element.parent().resource().toString();
} }
return false; return false;
} }
......
...@@ -93,9 +93,9 @@ export function getOutOfWorkspaceEditorResources(editorGroupService: IEditorGrou ...@@ -93,9 +93,9 @@ export function getOutOfWorkspaceEditorResources(editorGroupService: IEditorGrou
editorGroupService.getStacksModel().groups.forEach(group => { editorGroupService.getStacksModel().groups.forEach(group => {
const editors = group.getEditors(); const editors = group.getEditors();
editors.forEach(editor => { editors.forEach(editor => {
const fileResource = toResource(editor, { supportSideBySide: true, filter: 'file' }); const resource = toResource(editor, { supportSideBySide: true });
if (fileResource && !contextService.isInsideWorkspace(fileResource)) { if (resource && !contextService.isInsideWorkspace(resource)) {
resources.push(fileResource); resources.push(resource);
} }
}); });
}); });
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册