44 *--------------------------------------------------------------------------------------------*/
55'use strict' ;
66
7- import { TPromise } from 'vs/base/common/winjs.base' ;
7+ import { TPromise , Promise } from 'vs/base/common/winjs.base' ;
88import nls = require( 'vs/nls' ) ;
99import Paths = require( 'vs/base/common/paths' ) ;
1010import Json = require( 'vs/base/common/json' ) ;
@@ -16,10 +16,8 @@ import {getBaseThemeId, getSyntaxThemeId} from 'vs/platform/theme/common/themes'
1616import { IWindowService } from 'vs/workbench/services/window/electron-browser/windowService' ;
1717import { IStorageService , StorageScope } from 'vs/platform/storage/common/storage' ;
1818import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry' ;
19- import { IConfigurationService } from 'vs/platform/configuration/common/configuration' ;
2019import { Registry } from 'vs/platform/platform' ;
2120import { IConfigurationRegistry , Extensions } from 'vs/platform/configuration/common/configurationRegistry' ;
22- import { IFilesConfiguration } from 'vs/platform/files/common/files' ;
2321import { Extensions as JSONExtensions , IJSONContributionRegistry } from 'vs/platform/jsonschemas/common/jsonContributionRegistry' ;
2422import { IJSONSchema } from 'vs/base/common/jsonSchema' ;
2523
@@ -34,8 +32,10 @@ import pfs = require('vs/base/node/pfs');
3432const DEFAULT_THEME_ID = 'vs-dark vscode-theme-defaults-themes-dark_plus-json' ;
3533const DEFAULT_FILE_ICONS = 'vs-standard' ;
3634
37- const THEME_CHANNEL = 'vscode:changeTheme' ;
38- const THEME_PREF = 'workbench.theme' ;
35+ const COLOR_THEME_CHANNEL = 'vscode:changeColorTheme' ;
36+ const ICON_THEME_CHANNEL = 'vscode:changeIconTheme' ;
37+ const COLOR_THEME_PREF = 'workbench.theme' ;
38+ const ICON_THEME_PREF = 'workbench.iconTheme' ;
3939
4040let defaultBaseTheme = getBaseThemeId ( DEFAULT_THEME_ID ) ;
4141
@@ -172,19 +172,18 @@ export class ThemeService implements IThemeService {
172172 private onColorThemeChange : Emitter < string > ;
173173
174174 private knownFileIconContributions : IInternalThemeData [ ] ;
175- private currentFileIcons : string ;
175+ private currentIconTheme : string ;
176176
177177 constructor (
178178 @IExtensionService private extensionService : IExtensionService ,
179179 @IWindowService private windowService : IWindowService ,
180180 @IStorageService private storageService : IStorageService ,
181- @IConfigurationService private configurationService : IConfigurationService ,
182181 @ITelemetryService private telemetryService : ITelemetryService ) {
183182
184183 this . knownThemes = [ ] ;
185184 this . onColorThemeChange = new Emitter < string > ( ) ;
186185 this . knownFileIconContributions = [ ] ;
187- this . currentFileIcons = null ;
186+ this . currentIconTheme = '' ;
188187
189188 themesExtPoint . setHandler ( ( extensions ) => {
190189 for ( let ext of extensions ) {
@@ -193,7 +192,7 @@ export class ThemeService implements IThemeService {
193192 } ) ;
194193
195194 windowService . onBroadcast ( e => {
196- if ( e . channel === THEME_CHANNEL && typeof e . payload === 'string' ) {
195+ if ( e . channel === COLOR_THEME_CHANNEL && typeof e . payload === 'string' ) {
197196 this . setColorTheme ( e . payload , false ) ;
198197 }
199198 } ) ;
@@ -204,32 +203,31 @@ export class ThemeService implements IThemeService {
204203 }
205204 } ) ;
206205
207- const settings = configurationService . getConfiguration < IFilesConfiguration > ( ) ;
208- let iconTheme = settings && settings . files && settings . files . iconTheme ;
209- if ( iconTheme ) {
210- this . setFileIcons ( iconTheme ) ;
211- }
212-
213- configurationService . onDidUpdateConfiguration ( e => {
214- let filesConfig = e . config . files ;
215- let iconTheme = filesConfig && filesConfig . iconTheme ;
216- this . setFileIcons ( iconTheme ) ;
206+ windowService . onBroadcast ( e => {
207+ if ( e . channel === ICON_THEME_CHANNEL && typeof e . payload === 'string' ) {
208+ this . setFileIconTheme ( e . payload , false ) ;
209+ }
217210 } ) ;
218211 }
219212
220213 public get onDidColorThemeChange ( ) : Event < string > {
221214 return this . onColorThemeChange . event ;
222215 }
223216
224- public initialize ( container : HTMLElement ) : TPromise < boolean > {
217+ public initialize ( container : HTMLElement ) : TPromise < void > {
225218 this . container = container ;
226219
227- let themeId = this . storageService . get ( THEME_PREF , StorageScope . GLOBAL , null ) ;
220+ let themeId = this . storageService . get ( COLOR_THEME_PREF , StorageScope . GLOBAL , null ) ;
228221 if ( ! themeId ) {
229222 themeId = DEFAULT_THEME_ID ;
230- this . storageService . store ( THEME_PREF , themeId , StorageScope . GLOBAL ) ;
223+ this . storageService . store ( COLOR_THEME_PREF , themeId , StorageScope . GLOBAL ) ;
231224 }
232- return this . setColorTheme ( themeId , false ) ;
225+ let iconThemeId = this . storageService . get ( ICON_THEME_PREF , StorageScope . GLOBAL , null ) ;
226+ return Promise . join ( [
227+ this . setColorTheme ( themeId , false ) ,
228+ this . setFileIconTheme ( iconThemeId , false )
229+ ] ) ;
230+
233231 }
234232
235233 public setColorTheme ( themeId : string , broadcastToAllWindows : boolean ) : TPromise < boolean > {
@@ -238,7 +236,7 @@ export class ThemeService implements IThemeService {
238236 }
239237 if ( themeId === this . currentTheme ) {
240238 if ( broadcastToAllWindows ) {
241- this . windowService . broadcast ( { channel : THEME_CHANNEL , payload : themeId } ) ;
239+ this . windowService . broadcast ( { channel : COLOR_THEME_CHANNEL , payload : themeId } ) ;
242240 }
243241 return TPromise . as ( true ) ;
244242 }
@@ -255,9 +253,9 @@ export class ThemeService implements IThemeService {
255253 $ ( this . container ) . addClass ( newThemeId ) ;
256254 }
257255
258- this . storageService . store ( THEME_PREF , newThemeId , StorageScope . GLOBAL ) ;
256+ this . storageService . store ( COLOR_THEME_PREF , newThemeId , StorageScope . GLOBAL ) ;
259257 if ( broadcastToAllWindows ) {
260- this . windowService . broadcast ( { channel : THEME_CHANNEL , payload : newThemeId } ) ;
258+ this . windowService . broadcast ( { channel : COLOR_THEME_CHANNEL , payload : newThemeId } ) ;
261259 } else {
262260 this . sendTelemetry ( newTheme ) ;
263261 }
@@ -268,7 +266,7 @@ export class ThemeService implements IThemeService {
268266 }
269267
270268 public getColorTheme ( ) {
271- return this . currentTheme || this . storageService . get ( THEME_PREF , StorageScope . GLOBAL , DEFAULT_THEME_ID ) ;
269+ return this . currentTheme || this . storageService . get ( COLOR_THEME_PREF , StorageScope . GLOBAL , DEFAULT_THEME_ID ) ;
272270 }
273271
274272 private findThemeData ( themeId : string , defaultId ?: string ) : TPromise < IInternalThemeData > {
@@ -399,48 +397,70 @@ export class ThemeService implements IThemeService {
399397 }
400398 }
401399
402- public getFileIcons ( ) : TPromise < IThemeData [ ] > {
400+ public getFileIconThemes ( ) : TPromise < IThemeData [ ] > {
403401 return this . extensionService . onReady ( ) . then ( isReady => {
404402 return this . knownFileIconContributions ;
405403 } ) ;
406404 }
407405
408- private setFileIcons ( fileIcons : string ) : TPromise < boolean > {
409- if ( fileIcons !== this . currentFileIcons ) {
410- this . currentFileIcons = fileIcons ;
411- return this . _updateFileIcons ( ) ;
406+ public getFileIconTheme ( ) {
407+ return this . currentIconTheme || this . storageService . get ( ICON_THEME_PREF , StorageScope . GLOBAL , '' ) ;
408+ }
409+
410+ public setFileIconTheme ( fileIcons : string , broadcastToAllWindows : boolean ) : TPromise < boolean > {
411+ fileIcons = fileIcons || '' ;
412+ if ( fileIcons === this . currentIconTheme ) {
413+ if ( broadcastToAllWindows ) {
414+ this . windowService . broadcast ( { channel : ICON_THEME_CHANNEL , payload : fileIcons } ) ;
415+ }
416+ return TPromise . as ( true ) ;
412417 }
413- return TPromise . as ( true ) ;
418+ let onApply = ( newIconTheme : IInternalThemeData ) => {
419+ let newIconThemeId = newIconTheme ? newIconTheme . id : '' ;
420+
421+ this . storageService . store ( ICON_THEME_PREF , newIconThemeId , StorageScope . GLOBAL ) ;
422+ if ( broadcastToAllWindows ) {
423+ this . windowService . broadcast ( { channel : ICON_THEME_CHANNEL , payload : newIconThemeId } ) ;
424+ } else if ( newIconTheme ) {
425+ this . sendTelemetry ( newIconTheme ) ;
426+ }
427+ } ;
428+
429+ this . currentIconTheme = fileIcons ;
430+ return this . _updateFileIcons ( onApply ) ;
414431 }
415432
416- private _updateFileIcons ( ) : TPromise < boolean > {
417- return this . getFileIcons ( ) . then ( allIconSets => {
433+ private _updateFileIcons ( onApply : ( theme : IInternalThemeData ) => void ) : TPromise < boolean > {
434+ return this . getFileIconThemes ( ) . then ( allIconSets => {
418435 let iconSetData ;
419436 for ( let iconSet of allIconSets ) {
420- if ( iconSet . id === this . currentFileIcons ) {
437+ if ( iconSet . id === this . currentIconTheme ) {
421438 iconSetData = < IInternalThemeData > iconSet ;
422439 break ;
423440 }
424441 }
425- return _applyFileIcons ( iconSetData ) ;
442+ return _applyFileIcons ( iconSetData , onApply ) ;
426443 } ) ;
427444 }
428445}
429446
430- function _applyFileIcons ( data : IInternalThemeData ) : TPromise < boolean > {
447+ function _applyFileIcons ( data : IInternalThemeData , onApply : ( theme : IInternalThemeData ) => void ) : TPromise < boolean > {
431448 if ( ! data ) {
432449 _applyRules ( '' , fileIconRulesClassName ) ;
450+ onApply ( data ) ;
433451 return TPromise . as ( true ) ;
434452 }
435453
436454 if ( data . styleSheetContent ) {
437455 _applyRules ( data . styleSheetContent , fileIconRulesClassName ) ;
456+ onApply ( data ) ;
438457 return TPromise . as ( true ) ;
439458 }
440459 return _loadFileIconsDocument ( data . path ) . then ( fileIconsDocument => {
441460 let styleSheetContent = _processFileIconsObject ( data . id , data . path , fileIconsDocument ) ;
442461 data . styleSheetContent = styleSheetContent ;
443462 _applyRules ( styleSheetContent , fileIconRulesClassName ) ;
463+ onApply ( data ) ;
444464 return true ;
445465 } , error => {
446466 return TPromise . wrapError ( nls . localize ( 'error.cannotloadfileicons' , "Unable to load {0}" , data . path ) ) ;
0 commit comments