@@ -55,7 +55,7 @@ import { clipboard } from 'electron';
5555import { IPartService } from 'vs/workbench/services/part/common/partService' ;
5656import { alert } from 'vs/base/browser/ui/aria/aria' ;
5757import { coalesce } from 'vs/base/common/arrays' ;
58- import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService' ;
58+ import { IWorkbenchThemeService , COLOR_THEME_SETTING } from 'vs/workbench/services/themes/common/workbenchThemeService' ;
5959
6060function toExtensionDescription ( local : ILocalExtension ) : IExtensionDescription {
6161 return {
@@ -147,7 +147,6 @@ export class InstallAction extends ExtensionAction {
147147 @IInstantiationService private readonly instantiationService : IInstantiationService ,
148148 @INotificationService private readonly notificationService : INotificationService ,
149149 @IOpenerService private readonly openerService : IOpenerService ,
150- @IQuickInputService private readonly quickInputService : IQuickInputService ,
151150 @IExtensionService private readonly runtimeExtensionService : IExtensionService ,
152151 @IWorkbenchThemeService private readonly workbenchThemeService : IWorkbenchThemeService
153152 ) {
@@ -183,8 +182,22 @@ export class InstallAction extends ExtensionAction {
183182
184183 const extension = await this . install ( this . extension ) ;
185184
186- if ( extension . local && extension . local . manifest . contributes && extension . local . manifest . contributes . themes && extension . local . manifest . contributes . themes . length ) {
187- return this . applyInstalledTheme ( extension . local ) ;
185+ if ( extension . local ) {
186+ const runningExtension = await this . getRunningExtension ( extension . local ) ;
187+ if ( runningExtension ) {
188+ const colorThemes = await this . workbenchThemeService . getColorThemes ( runningExtension . identifier ) ;
189+ const fileIconThemes = await this . workbenchThemeService . getFileIconThemes ( runningExtension . identifier ) ;
190+ if ( colorThemes . length && ! fileIconThemes . length ) {
191+ const action = this . instantiationService . createInstance ( SetColorThemeAction ) ;
192+ action . extension = extension ;
193+ return action . run ( true ) ;
194+ }
195+ if ( ! colorThemes . length && fileIconThemes . length ) {
196+ const action = this . instantiationService . createInstance ( SetFileIconThemeAction ) ;
197+ action . extension = extension ;
198+ return action . run ( true ) ;
199+ }
200+ }
188201 }
189202
190203 }
@@ -202,25 +215,6 @@ export class InstallAction extends ExtensionAction {
202215 } ) ;
203216 }
204217
205- private async applyInstalledTheme ( extension : ILocalExtension ) : Promise < void > {
206- const runningExtension = await this . getRunningExtension ( extension ) ;
207- if ( runningExtension ) {
208- const currentTheme = this . workbenchThemeService . getColorTheme ( ) ;
209- const themes = await this . workbenchThemeService . getColorThemes ( runningExtension . identifier ) ;
210- const delayer = new Delayer < void > ( 100 ) ;
211- const picks : ( IQuickPickItem | IQuickPickSeparator ) [ ] = themes . map ( theme => ( < IQuickPickItem > { label : theme . label , id : theme . id } ) ) ;
212- picks . push ( < IQuickPickSeparator > { type : 'separator' } ) ;
213- picks . push ( < IQuickPickItem > { label : localize ( 'stay with current theme' , "Stay with current theme ({0})" , currentTheme . label ) , id : currentTheme . id } ) ;
214- const pickedTheme = await this . quickInputService . pick (
215- picks ,
216- {
217- placeHolder : localize ( 'apply installed theme' , "Apply installed theme or press Escape to cancel." ) ,
218- onDidFocus : item => delayer . trigger ( ( ) => this . workbenchThemeService . setColorTheme ( item . id , ConfigurationTarget . MEMORY ) . then ( ( ) => undefined ) )
219- } ) ;
220- this . workbenchThemeService . setColorTheme ( pickedTheme ? pickedTheme . id : currentTheme . id , undefined ) ;
221- }
222- }
223-
224218 private async getRunningExtension ( extension : ILocalExtension ) : Promise < IExtensionDescription | null > {
225219 const runningExtension = await this . runtimeExtensionService . getExtension ( extension . identifier . id ) ;
226220 if ( runningExtension ) {
@@ -1111,6 +1105,138 @@ export class ReloadAction extends ExtensionAction {
11111105 }
11121106}
11131107
1108+ export class SetColorThemeAction extends ExtensionAction {
1109+
1110+ private static readonly EnabledClass = 'extension-action theme' ;
1111+ private static readonly DisabledClass = `${ SetColorThemeAction . EnabledClass } disabled` ;
1112+
1113+ private disposables : IDisposable [ ] = [ ] ;
1114+
1115+ constructor (
1116+ @IExtensionService extensionService : IExtensionService ,
1117+ @IWorkbenchThemeService private readonly workbenchThemeService : IWorkbenchThemeService ,
1118+ @IQuickInputService private readonly quickInputService : IQuickInputService ,
1119+ @IConfigurationService private readonly configurationService : IConfigurationService
1120+ ) {
1121+ super ( `extensions.colorTheme` , localize ( 'color theme' , "Set Color Theme" ) , SetColorThemeAction . DisabledClass , false ) ;
1122+ Event . any < any > ( extensionService . onDidChangeExtensions , workbenchThemeService . onDidColorThemeChange ) ( ( ) => this . update ( ) , this , this . disposables ) ;
1123+ this . update ( ) ;
1124+ }
1125+
1126+ async update ( ) : Promise < void > {
1127+ this . enabled = false ;
1128+ if ( this . extension ) {
1129+ const isInstalled = this . extension . state === ExtensionState . Installed ;
1130+ if ( isInstalled ) {
1131+ const colorThemes = await this . workbenchThemeService . getColorThemes ( new ExtensionIdentifier ( this . extension . identifier . id ) ) ;
1132+ this . enabled = colorThemes . length > 0 ;
1133+ }
1134+ }
1135+ this . class = this . enabled ? SetColorThemeAction . EnabledClass : SetColorThemeAction . DisabledClass ;
1136+ }
1137+
1138+ async run ( showCurrentTheme : boolean ) : Promise < any > {
1139+ await this . update ( ) ;
1140+ if ( ! this . enabled ) {
1141+ return ;
1142+ }
1143+ let colorThemes = await this . workbenchThemeService . getColorThemes ( new ExtensionIdentifier ( this . extension . identifier . id ) ) ;
1144+ const currentTheme = this . workbenchThemeService . getColorTheme ( ) ;
1145+ showCurrentTheme = showCurrentTheme || colorThemes . some ( t => t . id === currentTheme . id ) ;
1146+ if ( showCurrentTheme ) {
1147+ colorThemes = colorThemes . filter ( t => t . id !== currentTheme . id ) ;
1148+ }
1149+
1150+ const delayer = new Delayer < any > ( 100 ) ;
1151+ const picks : ( IQuickPickItem | IQuickPickSeparator ) [ ] = [ ] ;
1152+ picks . push ( ...colorThemes . map ( theme => ( < IQuickPickItem > { label : theme . label , id : theme . id } ) ) ) ;
1153+ if ( showCurrentTheme ) {
1154+ picks . push ( < IQuickPickSeparator > { type : 'separator' , label : localize ( 'current' , "Current" ) } ) ;
1155+ picks . push ( < IQuickPickItem > { label : currentTheme . label , id : currentTheme . id } ) ;
1156+ }
1157+ const pickedTheme = await this . quickInputService . pick (
1158+ picks ,
1159+ {
1160+ placeHolder : localize ( 'select color theme' , "Select Color Theme" ) ,
1161+ onDidFocus : item => delayer . trigger ( ( ) => this . workbenchThemeService . setColorTheme ( item . id , undefined ) )
1162+ } ) ;
1163+ let confValue = this . configurationService . inspect ( COLOR_THEME_SETTING ) ;
1164+ const target = typeof confValue . workspace !== 'undefined' ? ConfigurationTarget . WORKSPACE : ConfigurationTarget . USER ;
1165+ return this . workbenchThemeService . setColorTheme ( pickedTheme ? pickedTheme . id : currentTheme . id , target ) ;
1166+ }
1167+
1168+ dispose ( ) {
1169+ this . disposables = dispose ( this . disposables ) ;
1170+ super . dispose ( ) ;
1171+ }
1172+ }
1173+
1174+ export class SetFileIconThemeAction extends ExtensionAction {
1175+
1176+ private static readonly EnabledClass = 'extension-action theme' ;
1177+ private static readonly DisabledClass = `${ SetFileIconThemeAction . EnabledClass } disabled` ;
1178+
1179+ private disposables : IDisposable [ ] = [ ] ;
1180+
1181+ constructor (
1182+ @IExtensionService extensionService : IExtensionService ,
1183+ @IWorkbenchThemeService private readonly workbenchThemeService : IWorkbenchThemeService ,
1184+ @IQuickInputService private readonly quickInputService : IQuickInputService ,
1185+ @IConfigurationService private readonly configurationService : IConfigurationService
1186+ ) {
1187+ super ( `extensions.fileIconTheme` , localize ( 'file icon theme' , "Set File Icon Theme" ) , SetFileIconThemeAction . DisabledClass , false ) ;
1188+ Event . any < any > ( extensionService . onDidChangeExtensions , workbenchThemeService . onDidFileIconThemeChange ) ( ( ) => this . update ( ) , this , this . disposables ) ;
1189+ this . update ( ) ;
1190+ }
1191+
1192+ async update ( ) : Promise < void > {
1193+ this . enabled = false ;
1194+ if ( this . extension ) {
1195+ const isInstalled = this . extension . state === ExtensionState . Installed ;
1196+ if ( isInstalled ) {
1197+ const fileIconThemes = await this . workbenchThemeService . getFileIconThemes ( new ExtensionIdentifier ( this . extension . identifier . id ) ) ;
1198+ this . enabled = fileIconThemes . length > 0 ;
1199+ }
1200+ }
1201+ this . class = this . enabled ? SetFileIconThemeAction . EnabledClass : SetFileIconThemeAction . DisabledClass ;
1202+ }
1203+
1204+ async run ( showCurrentTheme : boolean ) : Promise < any > {
1205+ await this . update ( ) ;
1206+ if ( ! this . enabled ) {
1207+ return ;
1208+ }
1209+ let fileIconThemes = await this . workbenchThemeService . getFileIconThemes ( new ExtensionIdentifier ( this . extension . identifier . id ) ) ;
1210+ const currentTheme = this . workbenchThemeService . getFileIconTheme ( ) ;
1211+ showCurrentTheme = showCurrentTheme || fileIconThemes . some ( t => t . id === currentTheme . id ) ;
1212+ if ( showCurrentTheme ) {
1213+ fileIconThemes = fileIconThemes . filter ( t => t . id !== currentTheme . id ) ;
1214+ }
1215+
1216+ const delayer = new Delayer < any > ( 100 ) ;
1217+ const picks : ( IQuickPickItem | IQuickPickSeparator ) [ ] = [ ] ;
1218+ picks . push ( ...fileIconThemes . map ( theme => ( < IQuickPickItem > { label : theme . label , id : theme . id } ) ) ) ;
1219+ if ( showCurrentTheme ) {
1220+ picks . push ( < IQuickPickSeparator > { type : 'separator' , label : localize ( 'current' , "Current" ) } ) ;
1221+ picks . push ( < IQuickPickItem > { label : currentTheme . label , id : currentTheme . id } ) ;
1222+ }
1223+ const pickedTheme = await this . quickInputService . pick (
1224+ picks ,
1225+ {
1226+ placeHolder : localize ( 'select file icon theme' , "Select File Icon Theme" ) ,
1227+ onDidFocus : item => delayer . trigger ( ( ) => this . workbenchThemeService . setFileIconTheme ( item . id , undefined ) )
1228+ } ) ;
1229+ let confValue = this . configurationService . inspect ( COLOR_THEME_SETTING ) ;
1230+ const target = typeof confValue . workspace !== 'undefined' ? ConfigurationTarget . WORKSPACE : ConfigurationTarget . USER ;
1231+ return this . workbenchThemeService . setFileIconTheme ( pickedTheme ? pickedTheme . id : currentTheme . id , target ) ;
1232+ }
1233+
1234+ dispose ( ) {
1235+ this . disposables = dispose ( this . disposables ) ;
1236+ super . dispose ( ) ;
1237+ }
1238+ }
1239+
11141240export class OpenExtensionsViewletAction extends ShowViewletAction {
11151241
11161242 static ID = VIEWLET_ID ;
0 commit comments