1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { language } from 'vs/base/common/platform';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing';
import { ILocaleService } from 'vs/workbench/contrib/localization/common/locale';
import { ILanguagePackItem, ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks';
import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite';
import { IExtensionsViewPaneContainer, VIEWLET_ID as EXTENSIONS_VIEWLET_ID } from 'vs/workbench/contrib/extensions/common/extensions';
import { ViewContainerLocation } from 'vs/workbench/common/views';
import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress';
import { localize } from 'vs/nls';
import { toAction } from 'vs/base/common/actions';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { stripComments } from 'vs/base/common/stripComments';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
export class NativeLocaleService implements ILocaleService {
_serviceBrand: undefined;
constructor(
@IJSONEditingService private readonly jsonEditingService: IJSONEditingService,
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@INotificationService private readonly notificationService: INotificationService,
@ILanguagePackService private readonly languagePackService: ILanguagePackService,
@IPaneCompositePartService private readonly paneCompositePartService: IPaneCompositePartService,
@IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService,
@IProgressService private readonly progressService: IProgressService,
@ITextFileService private readonly textFileService: ITextFileService,
@IEditorService private readonly editorService: IEditorService
) { }
private async validateLocaleFile(): Promise<boolean> {
try {
const content = await this.textFileService.read(this.environmentService.argvResource, { encoding: 'utf8' });
// This is the same logic that we do where argv.json is parsed so mirror that:
// https://github.com/microsoft/vscode/blob/32d40cf44e893e87ac33ac4f08de1e5f7fe077fc/src/main.js#L238-L246
JSON.parse(stripComments(content.value));
} catch (error) {
this.notificationService.notify({
severity: Severity.Error,
message: localize('argvInvalid', 'Unable to write display language. Please open the runtime settings, correct errors/warnings in it and try again.'),
actions: {
primary: [
toAction({
id: 'openArgv',
label: localize('openArgv', "Open Runtime Settings"),
run: () => this.editorService.openEditor({ resource: this.environmentService.argvResource })
})
]
}
});
return false;
}
return true;
}
private async writeLocaleValue(locale: string | undefined): Promise<boolean> {
if (!(await this.validateLocaleFile())) {
return false;
}
await this.jsonEditingService.write(this.environmentService.argvResource, [{ path: ['locale'], value: locale }], true);
return true;
}
async setLocale(languagePackItem: ILanguagePackItem): Promise<boolean> {
const locale = languagePackItem.id;
if (locale === language || (!locale && language === 'en')) {
return false;
}
const installedLanguages = await this.languagePackService.getInstalledLanguages();
try {
// Only Desktop has the concept of installing language packs so we only do this for Desktop
// and only if the language pack is not installed
if (!installedLanguages.some(installedLanguage => installedLanguage.id === languagePackItem.id)) {
// Only actually install a language pack from Microsoft
if (languagePackItem.galleryExtension?.publisher.toLowerCase() !== 'ms-ceintl') {
// Show the view so the user can see the language pack that they should install
// as of now, there are no 3rd party language packs available on the Marketplace.
const viewlet = await this.paneCompositePartService.openPaneComposite(EXTENSIONS_VIEWLET_ID, ViewContainerLocation.Sidebar);
(viewlet?.getViewPaneContainer() as IExtensionsViewPaneContainer).search(`@id:${languagePackItem.extensionId}`);
return false;
}
await this.progressService.withProgress(
{
location: ProgressLocation.Notification,
title: localize('installing', "Installing {0} language support...", languagePackItem.label),
},
progress => this.extensionManagementService.installFromGallery(languagePackItem.galleryExtension!, {
// Setting this to false is how you get the extension to be synced with Settings Sync (if enabled).
isMachineScoped: false,
})
);
}
return await this.writeLocaleValue(locale);
} catch (err) {
this.notificationService.error(err);
return false;
}
}
async clearLocalePreference(): Promise<boolean> {
if (language === 'en') {
return false;
}
try {
return await this.writeLocaleValue(undefined);
} catch (err) {
this.notificationService.error(err);
return false;
}
}
}
|